Version 2.18.0-171.0.dev

Merge commit 'de8f84f62d58ab4d124a9706b34ae81de7b1ae34' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2670af5..ac2b73a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -56,6 +56,11 @@
 
 #### `dart:io`
 
+- **Breaking Change** [#34218](https://github.com/dart-lang/sdk/issues/34218):
+  Constants in `dart:io`'s networking APIs following the `SCREAMING_CAPS`
+  convention have been removed (they were previously deprecated). Please use
+  the corresponding `lowerCamelCase` constants instead.
+
 - **Breaking Change** [#45630][]: The Dart VM no longer automatically restores
     the initial terminal settings upon exit. Programs that change the `Stdin`
     settings `lineMode` and `echoMode` are now responsible for restoring the
@@ -113,28 +118,33 @@
 
 #### Linter
 
-Updated the Linter to `1.24.0`, which includes changes that
+Updated the Linter to `1.25.0`, which includes changes that
 
-- fixes `prefer_final_parameters` to support super parameters.
-- adds new lint: `unnecessary_to_list_in_spreads`.
-- fixes `unawaited_futures` to handle string interpolated
+- add new lint: `discarded_futures`.
+- improve message and highlight range for `no_duplicate_case_values`
+- improve performance for `lines_longer_than_80_chars`,
+  `prefer_const_constructors_in_immutables`, and
+  `prefer_initializing_formals`.
+- fix `prefer_final_parameters` to support super parameters.
+- add new lint: `unnecessary_to_list_in_spreads`.
+- fix `unawaited_futures` to handle string interpolated
   futures.
-- updates `use_colored_box` to not flag nullable colors,
-- adds new lint: 
+- update `use_colored_box` to not flag nullable colors,
+- add new lint: 
   `unnecessary_null_aware_operator_on_extension_on_nullable`.
-- fixes `no_leading_underscores_for_local_identifiers`
+- fix `no_leading_underscores_for_local_identifiers`
   to lint local function declarations.
-- fixes `avoid_init_to_null` to correctly handle super
+- fix `avoid_init_to_null` to correctly handle super
   initializing defaults that are non-null.
-- updates `no_leading_underscores_for_local_identifiers`
+- update `no_leading_underscores_for_local_identifiers`
   to allow identifiers with just underscores.
-- fixes `flutter_style_todos` to support usernames that
+- fix `flutter_style_todos` to support usernames that
   start with a digit.
-- updates `require_trailing_commas` to handle functions
+- update `require_trailing_commas` to handle functions
   in asserts and multi-line strings.
-- updates `unsafe_html` to allow assignments to
+- update `unsafe_html` to allow assignments to
   `img.src`.
-- fixes `unnecessary_null_checks` to properly handle map
+- fix `unnecessary_null_checks` to properly handle map
   literal entries.
 
 #### Pub
diff --git a/DEPS b/DEPS
index b09d373..f1e605f 100644
--- a/DEPS
+++ b/DEPS
@@ -106,7 +106,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164.
   "dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea",
 
-  "dartdoc_rev": "8549817bb1b59808108e83ef0e513157cb572d2a",
+  "dartdoc_rev": "f5bcc4bd46f4ce956b6c27ebaf741f6e90d7fca9",
   "devtools_rev": "51ac983d2db7eb19b3ce5956cb70b769d74fe784",
   "ffi_rev": "0c8364a728cfe4e4ba859c53b99d56b3dbe3add4",
   "file_rev": "0132eeedea2933513bf230513a766a8baeab0c4f",
@@ -120,7 +120,7 @@
   "intl_rev": "9145f308f1458f37630a1ffce3b7d3b471ebbc56",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "2de9a1f9821807fa2c85fd48e2f70b9cbcddcb67",
-  "linter_rev": "a8529c6692922b45bc287543b355c90d7b1286d3", # 1.24.0
+  "linter_rev": "1ddc70948d94f2449fec69a95e3ceb7b6b6c8348", # 1.25.0
   "lints_rev": "8294e5648ab49474541527e2911e72e4c5aefe55",
   "logging_rev": "f6979e3bc3b6e1847a08335b7eb6304e18986195",
   "markdown_rev": "e3f4bd28c9e61b522f75f291d4d6cfcfeccd83ee", # 5.0.0
diff --git a/benchmarks/IsolateSendExit/dart/IsolateSendExitLatency.dart b/benchmarks/IsolateSendExitLatency/dart/IsolateSendExitLatency.dart
similarity index 100%
rename from benchmarks/IsolateSendExit/dart/IsolateSendExitLatency.dart
rename to benchmarks/IsolateSendExitLatency/dart/IsolateSendExitLatency.dart
diff --git a/benchmarks/IsolateSendExit/dart/latency.dart b/benchmarks/IsolateSendExitLatency/dart/latency.dart
similarity index 100%
rename from benchmarks/IsolateSendExit/dart/latency.dart
rename to benchmarks/IsolateSendExitLatency/dart/latency.dart
diff --git a/benchmarks/IsolateSendExit/dart2/IsolateSendExitLatency.dart b/benchmarks/IsolateSendExitLatency/dart2/IsolateSendExitLatency.dart
similarity index 100%
rename from benchmarks/IsolateSendExit/dart2/IsolateSendExitLatency.dart
rename to benchmarks/IsolateSendExitLatency/dart2/IsolateSendExitLatency.dart
diff --git a/benchmarks/IsolateSendExit/dart2/latency.dart b/benchmarks/IsolateSendExitLatency/dart2/latency.dart
similarity index 100%
rename from benchmarks/IsolateSendExit/dart2/latency.dart
rename to benchmarks/IsolateSendExitLatency/dart2/latency.dart
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
index 23e0093..a61f47f 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
@@ -16,9 +16,9 @@
 
 /// Replaces:
 ///   1) Factory constructors in classes with `@staticInterop` annotations with
-///      calls to `js_util_wasm.callConstructorVarArgs`.
+///      calls to `js_util.callConstructor`.
 ///   2) External methods in `@staticInterop` class extensions to their
-///      corresponding `js_util_wasm` calls.
+///      corresponding `js_util` calls.
 /// TODO(joshualitt): In the long term we'd like to have the same
 /// `JsUtilOptimizer` for all web backends. This is to ensure uniform semantics
 /// across all web backends. Some known challenges remain, and there may be
@@ -45,21 +45,18 @@
 class JsUtilWasmOptimizer extends Transformer {
   final Procedure _callMethodTarget;
   final Procedure _callConstructorTarget;
-  final Procedure _globalThisTarget;
   final Procedure _getPropertyTarget;
   final Procedure _setPropertyTarget;
-  final Procedure _jsifyTarget;
   final Procedure _jsifyRawTarget;
-  final Procedure _dartifyTarget;
   final Procedure _newObjectTarget;
   final Procedure _wrapDartCallbackTarget;
   final Procedure _allowInteropTarget;
-  final Class _jsValueClass;
   final Class _wasmAnyRefClass;
   final Class _objectClass;
   final Class _pragmaClass;
   final Field _pragmaName;
   final Field _pragmaOptions;
+  final Member _globalThisMember;
   int _callbackTrampolineN = 1;
 
   final CoreTypes _coreTypes;
@@ -68,30 +65,24 @@
   final Set<Class> _transformedClasses = {};
 
   JsUtilWasmOptimizer(this._coreTypes, ClassHierarchy hierarchy)
-      : _callMethodTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'callMethodVarArgs'),
-        _globalThisTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'globalThis'),
-        _callConstructorTarget = _coreTypes.index.getTopLevelProcedure(
-            'dart:js_util_wasm', 'callConstructorVarArgs'),
+      : _callMethodTarget =
+            _coreTypes.index.getTopLevelProcedure('dart:js_util', 'callMethod'),
+        _globalThisMember = _coreTypes.index
+            .getTopLevelMember('dart:js_util', 'get:globalThis'),
+        _callConstructorTarget = _coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'callConstructor'),
         _getPropertyTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'getProperty'),
+            .getTopLevelProcedure('dart:js_util', 'getProperty'),
         _setPropertyTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'setProperty'),
-        _jsifyTarget =
-            _coreTypes.index.getTopLevelProcedure('dart:js_util_wasm', 'jsify'),
+            .getTopLevelProcedure('dart:js_util', 'setProperty'),
         _jsifyRawTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'jsifyRaw'),
-        _dartifyTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'dartify'),
+            .getTopLevelProcedure('dart:_js_helper', 'jsifyRaw'),
         _wrapDartCallbackTarget = _coreTypes.index
             .getTopLevelProcedure('dart:js_util_wasm', '_wrapDartCallback'),
-        _newObjectTarget = _coreTypes.index
-            .getTopLevelProcedure('dart:js_util_wasm', 'newObject'),
+        _newObjectTarget =
+            _coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
         _allowInteropTarget = _coreTypes.index
             .getTopLevelProcedure('dart:js_util_wasm', 'allowInterop'),
-        _jsValueClass =
-            _coreTypes.index.getClass('dart:js_util_wasm', 'JSValue'),
         _wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
         _objectClass = _coreTypes.objectClass,
         _pragmaClass = _coreTypes.pragmaClass,
@@ -120,6 +111,7 @@
 
   @override
   StaticInvocation visitStaticInvocation(StaticInvocation node) {
+    node = super.visitStaticInvocation(node) as StaticInvocation;
     if (node.target == _allowInteropTarget) {
       Expression argument = node.arguments.positional.single;
       DartType functionType = argument.getStaticType(_staticTypeContext);
@@ -208,14 +200,11 @@
     return _extensionMemberIndex!;
   }
 
-  DartType get _nullableJSValueType =>
-      _jsValueClass.getThisType(_coreTypes, Nullability.nullable);
+  DartType get _nullableObjectType =>
+      _coreTypes.objectRawType(Nullability.nullable);
 
-  DartType get _nonNullableJSValueType =>
-      _jsValueClass.getThisType(_coreTypes, Nullability.nonNullable);
-
-  Expression _dartify(Expression expression) =>
-      StaticInvocation(_dartifyTarget, Arguments([expression]));
+  DartType get _nonNullableObjectType =>
+      _coreTypes.objectRawType(Nullability.nonNullable);
 
   /// Creates a callback trampoline for the given [function]. This callback
   /// trampoline expects a Dart callback as its first argument, followed by all
@@ -298,17 +287,7 @@
         Arguments([argument, StringLiteral(callbackTrampolineName)]));
   }
 
-  Expression _jsifyVariable(Procedure node, VariableDeclaration variable) {
-    if (variable.type is FunctionType) {
-      return _allowInterop(
-          node, variable.type as FunctionType, VariableGet(variable));
-    } else {
-      return StaticInvocation(_jsifyTarget, Arguments([VariableGet(variable)]));
-    }
-  }
-
-  StaticInvocation get _globalThis =>
-      StaticInvocation(_globalThisTarget, Arguments([]));
+  StaticGet get _globalThis => StaticGet(_globalThisMember);
 
   /// Takes a list of [selectors] and returns an object off of
   /// `globalThis`. We could optimize this with a custom method built with
@@ -329,8 +308,9 @@
   Block _getExternalAnonymousConstructorBody(Procedure node) {
     List<Statement> body = [];
     final object = VariableDeclaration('|anonymousObject',
-        initializer: StaticInvocation(_newObjectTarget, Arguments([])),
-        type: _nonNullableJSValueType);
+        initializer: StaticInvocation(
+            _newObjectTarget, Arguments([], types: [node.function.returnType])),
+        type: _nonNullableObjectType);
     body.add(object);
     for (VariableDeclaration variable in node.function.namedParameters) {
       body.add(ExpressionStatement(
@@ -342,7 +322,7 @@
 
   /// Returns a new function body for the given [node] external method.
   ///
-  /// The new function body will call `js_util_wasm.callConstructorVarArgs`
+  /// The new function body will call `js_util.callConstructor`
   /// for the given external method.
   ReturnStatement _getExternalCallConstructorBody(
       Procedure node, String constructorName) {
@@ -350,13 +330,14 @@
     var callConstructorInvocation = StaticInvocation(
         _callConstructorTarget,
         Arguments([
-          _globalThis,
-          StringLiteral(constructorName),
+          _getProperty(node, _globalThis, constructorName),
           ListLiteral(
               function.positionalParameters
-                  .map((arg) => _jsifyVariable(node, arg))
+                  .map<Expression>((value) => VariableGet(value))
                   .toList(),
-              typeArgument: _nonNullableJSValueType)
+              typeArgument: _nullableObjectType)
+        ], types: [
+          node.function.returnType
         ]))
       ..fileOffset = node.fileOffset;
     return ReturnStatement(callConstructorInvocation);
@@ -365,17 +346,19 @@
   /// Returns a new [Expression] for the given [node] external getter.
   ///
   /// The new [Expression] is equivalent to:
-  /// `js_util_wasm.getProperty([object], [getterName])`.
+  /// `js_util.getProperty([object], [getterName])`.
   Expression _getProperty(
           Procedure node, Expression object, String getterName) =>
       StaticInvocation(
-          _getPropertyTarget, Arguments([object, StringLiteral(getterName)]))
+          _getPropertyTarget,
+          Arguments([object, StringLiteral(getterName)],
+              types: [node.function.returnType]))
         ..fileOffset = node.fileOffset;
 
   /// Returns a new function body for the given [node] external getter.
   ReturnStatement _getExternalGetterBody(
           Procedure node, Expression object, String getterName) =>
-      ReturnStatement(_dartify(_getProperty(node, object, getterName)));
+      ReturnStatement(_getProperty(node, object, getterName));
 
   ReturnStatement _getExternalExtensionGetterBody(Procedure node) =>
       _getExternalGetterBody(
@@ -390,19 +373,19 @@
   /// Returns a new [Expression] for the given [node] external setter.
   ///
   /// The new [Expression] is equivalent to:
-  /// `js_util_wasm.setProperty([object], [setterName], [value])`.
+  /// `js_util.setProperty([object], [setterName], [value])`.
   Expression _setProperty(Procedure node, Expression object, String setterName,
           VariableDeclaration value) =>
       StaticInvocation(
           _setPropertyTarget,
-          Arguments(
-              [object, StringLiteral(setterName), _jsifyVariable(node, value)]))
+          Arguments([object, StringLiteral(setterName), VariableGet(value)],
+              types: [node.function.returnType]))
         ..fileOffset = node.fileOffset;
 
   /// Returns a new function body for the given [node] external setter.
   ReturnStatement _getExternalSetterBody(Procedure node, Expression object,
           String setterName, VariableDeclaration value) =>
-      ReturnStatement(_dartify(_setProperty(node, object, setterName, value)));
+      ReturnStatement(_setProperty(node, object, setterName, value));
 
   ReturnStatement _getExternalExtensionSetterBody(Procedure node) {
     final parameters = node.function.positionalParameters;
@@ -419,18 +402,20 @@
   /// Returns a new function body for the given [node] external method.
   ///
   /// The new function body is equivalent to:
-  /// `js_util_wasm.callMethodVarArgs([object], [methodName], [values])`.
+  /// `js_util.callMethod([object], [methodName], [values])`.
   ReturnStatement _getExternalMethodBody(Procedure node, Expression object,
       String methodName, List<VariableDeclaration> values) {
-    final callMethodInvocation = _dartify(StaticInvocation(
+    final callMethodInvocation = StaticInvocation(
         _callMethodTarget,
         Arguments([
           object,
           StringLiteral(methodName),
           ListLiteral(
-              values.map((value) => _jsifyVariable(node, value)).toList(),
-              typeArgument: _nullableJSValueType)
-        ])))
+              values.map<Expression>((value) => VariableGet(value)).toList(),
+              typeArgument: _nullableObjectType)
+        ], types: [
+          node.function.returnType
+        ]))
       ..fileOffset = node.fileOffset;
     return ReturnStatement(callMethodInvocation);
   }
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 9c7edcb..fdedb8f 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -17,7 +17,8 @@
 const jsonEncoder = JsonEncoder.withIndent('    ');
 
 /// A special text edit with an additional change annotation.
-///  @since 3.16.0.
+///
+/// @since 3.16.0.
 class AnnotatedTextEdit implements TextEdit, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     AnnotatedTextEdit.canParse,
@@ -43,7 +44,7 @@
     );
   }
 
-  /// The actual annotation identifier.
+  /// The actual identifier of the change annotation
   final String annotationId;
 
   /// The string to be inserted. For delete operations use an empty string.
@@ -149,6 +150,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters passed via a apply workspace edit request.
 class ApplyWorkspaceEditParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ApplyWorkspaceEditParams.canParse,
@@ -243,6 +245,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The result returned from the apply workspace edit request.
+///
+/// @since 3.17 renamed from ApplyWorkspaceEditResponse
 class ApplyWorkspaceEditResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ApplyWorkspaceEditResult.canParse,
@@ -273,7 +278,7 @@
 
   /// Depending on the client's failure handling strategy `failedChange` might
   /// contain the index of the change that failed. This property is only
-  /// available if the client signals a `failureHandling` strategy in its client
+  /// available if the client signals a `failureHandlingStrategy` in its client
   /// capabilities.
   final int? failedChange;
 
@@ -365,6 +370,168 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A base for all symbol information.
+class BaseSymbolInformation implements ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    BaseSymbolInformation.canParse,
+    BaseSymbolInformation.fromJson,
+  );
+
+  BaseSymbolInformation({
+    this.containerName,
+    required this.kind,
+    required this.name,
+    this.tags,
+  });
+  static BaseSymbolInformation fromJson(Map<String, Object?> json) {
+    if (SymbolInformation.canParse(json, nullLspJsonReporter)) {
+      return SymbolInformation.fromJson(json);
+    }
+    if (WorkspaceSymbol.canParse(json, nullLspJsonReporter)) {
+      return WorkspaceSymbol.fromJson(json);
+    }
+    final containerNameJson = json['containerName'];
+    final containerName = containerNameJson as String?;
+    final kindJson = json['kind'];
+    final kind = SymbolKind.fromJson(kindJson as int);
+    final nameJson = json['name'];
+    final name = nameJson as String;
+    final tagsJson = json['tags'];
+    final tags = (tagsJson as List<Object?>?)
+        ?.map((item) => SymbolTag.fromJson(item as int))
+        .toList();
+    return BaseSymbolInformation(
+      containerName: containerName,
+      kind: kind,
+      name: name,
+      tags: tags,
+    );
+  }
+
+  /// The name of the symbol containing this symbol. This information is for
+  /// user interface purposes (e.g. to render a qualifier in the user interface
+  /// if necessary). It can't be used to re-infer a hierarchy for the document
+  /// symbols.
+  final String? containerName;
+
+  /// The kind of this symbol.
+  final SymbolKind kind;
+
+  /// The name of this symbol.
+  final String name;
+
+  /// Tags for this symbol.
+  ///
+  /// @since 3.16.0
+  final List<SymbolTag>? tags;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    if (containerName != null) {
+      result['containerName'] = containerName;
+    }
+    result['kind'] = kind.toJson();
+    result['name'] = name;
+    if (tags != null) {
+      result['tags'] = tags?.map((item) => item.toJson()).toList();
+    }
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      reporter.push('containerName');
+      try {
+        final containerName = obj['containerName'];
+        if (containerName != null && containerName is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('kind');
+      try {
+        if (!obj.containsKey('kind')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final kind = obj['kind'];
+        if (kind == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!SymbolKind.canParse(kind, reporter)) {
+          reporter.reportError('must be of type SymbolKind');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('name');
+      try {
+        if (!obj.containsKey('name')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final name = obj['name'];
+        if (name == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (name is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('tags');
+      try {
+        final tags = obj['tags'];
+        if (tags != null &&
+            (tags is! List<Object?> ||
+                tags.any((item) => !SymbolTag.canParse(item, reporter)))) {
+          reporter.reportError('must be of type List<SymbolTag>');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type BaseSymbolInformation');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is BaseSymbolInformation &&
+        other.runtimeType == BaseSymbolInformation) {
+      return containerName == other.containerName &&
+          kind == other.kind &&
+          name == other.name &&
+          listEqual(tags, other.tags, (SymbolTag a, SymbolTag b) => a == b) &&
+          true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        containerName,
+        kind,
+        name,
+        lspHashCode(tags),
+      );
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
+/// @since 3.16.0
 class CallHierarchyClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CallHierarchyClientCapabilities.canParse,
@@ -432,6 +599,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents an incoming call, e.g. a caller of a method or constructor.
+///
+/// @since 3.16.0
 class CallHierarchyIncomingCall implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CallHierarchyIncomingCall.canParse,
@@ -459,7 +629,7 @@
   final CallHierarchyItem from;
 
   /// The ranges at which the calls appear. This is relative to the caller
-  /// denoted by [`this.from`](#CallHierarchyIncomingCall.from).
+  /// denoted by `this.from`.
   final List<Range> fromRanges;
 
   @override
@@ -538,6 +708,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `callHierarchy/incomingCalls` request.
+///
+/// @since 3.16.0
 class CallHierarchyIncomingCallsParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -674,6 +847,10 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents programming constructs like functions or constructors in the
+/// context of call hierarchy.
+///
+/// @since 3.16.0
 class CallHierarchyItem implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CallHierarchyItem.canParse,
@@ -740,8 +917,7 @@
   final Range range;
 
   /// The range that should be selected and revealed when this symbol is being
-  /// picked, e.g. the name of a function. Must be contained by the
-  /// [`range`](#CallHierarchyItem.range).
+  /// picked, e.g. the name of a function. Must be contained by the `range`.
   final Range selectionRange;
 
   /// Tags for this item.
@@ -923,6 +1099,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Call hierarchy options used during static registration.
+///
+/// @since 3.16.0
 class CallHierarchyOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CallHierarchyOptions.canParse,
@@ -990,6 +1169,10 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents an outgoing call, e.g. calling a getter from a method or a method
+/// from a constructor etc.
+///
+/// @since 3.16.0
 class CallHierarchyOutgoingCall implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CallHierarchyOutgoingCall.canParse,
@@ -1014,7 +1197,8 @@
   }
 
   /// The range at which this item is called. This is the range relative to the
-  /// caller, e.g the item passed to `callHierarchy/outgoingCalls` request.
+  /// caller, e.g the item passed to `provideCallHierarchyOutgoingCalls` and not
+  /// `this.to`.
   final List<Range> fromRanges;
 
   /// The item that is called.
@@ -1096,6 +1280,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `callHierarchy/outgoingCalls` request.
+///
+/// @since 3.16.0
 class CallHierarchyOutgoingCallsParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -1232,6 +1419,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `textDocument/prepareCallHierarchy` request.
+///
+/// @since 3.16.0
 class CallHierarchyPrepareParams
     implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -1368,6 +1558,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Call hierarchy options used during static or dynamic registration.
+///
+/// @since 3.16.0
 class CallHierarchyRegistrationOptions
     implements
         CallHierarchyOptions,
@@ -1575,7 +1768,8 @@
 }
 
 /// Additional information that describes document changes.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class ChangeAnnotation implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ChangeAnnotation.canParse,
@@ -1695,6 +1889,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Defines the capabilities provided by the client.
 class ClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ClientCapabilities.canParse,
@@ -1750,11 +1945,13 @@
   final Object? experimental;
 
   /// General client capabilities.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final GeneralClientCapabilities? general;
 
   /// Capabilities specific to the notebook document support.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final NotebookDocumentClientCapabilities? notebookDocument;
 
   /// Text document specific client capabilities.
@@ -1951,7 +2148,8 @@
 
   /// A data entry field that is preserved on a code action between a
   /// `textDocument/codeAction` and a `codeAction/resolve` request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Object? data;
 
   /// The diagnostics that this code action resolves.
@@ -1962,17 +2160,21 @@
   /// Clients should follow the following guidelines regarding disabled code
   /// actions:
   ///
-  /// - Disabled code actions are not shown in automatic lightbulbs code
-  ///   action menus.
+  ///   - Disabled code actions are not shown in automatic
+  /// [lightbulbs](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)
+  ///     code action menus.
   ///
-  /// - Disabled actions are shown as faded out in the code action menu when
-  ///   the user request a more specific type of code action, such as
-  ///   refactorings.
+  ///   - Disabled actions are shown as faded out in the code action menu when
+  /// the user requests a more specific type
+  ///     of code action, such as refactorings.
   ///
-  /// - If the user has a keybinding that auto applies a code action and only
-  ///   a disabled code actions are returned, the client should show the user
-  ///   an error message with `reason` in the editor.
-  ///  @since 3.16.0
+  ///   - If the user has a
+  /// [keybinding](https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions)
+  ///     that auto applies a code action and only disabled code actions are
+  /// returned, the client should show the user an
+  ///     error message with `reason` in the editor.
+  ///
+  /// @since 3.16.0
   final CodeActionDisabled? disabled;
 
   /// The workspace edit this code action performs.
@@ -1984,7 +2186,8 @@
   /// A quick fix should be marked preferred if it properly addresses the
   /// underlying error. A refactoring should be marked preferred if it is the
   /// most reasonable choice of actions to take.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? isPreferred;
 
   /// The kind of the code action.
@@ -2148,6 +2351,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The Client Capabilities of a CodeActionRequest.
 class CodeActionClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeActionClientCapabilities.canParse,
@@ -2195,19 +2399,23 @@
     );
   }
 
-  /// The client supports code action literals as a valid response of the
-  /// `textDocument/codeAction` request.
-  ///  @since 3.8.0
+  /// The client support code action literals of type `CodeAction` as a valid
+  /// response of the `textDocument/codeAction` request. If the property is not
+  /// set the request can only return `Command` literals.
+  ///
+  /// @since 3.8.0
   final CodeActionClientCapabilitiesCodeActionLiteralSupport?
       codeActionLiteralSupport;
 
   /// Whether code action supports the `data` property which is preserved
   /// between a `textDocument/codeAction` and a `codeAction/resolve` request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? dataSupport;
 
   /// Whether code action supports the `disabled` property.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? disabledSupport;
 
   /// Whether code action supports dynamic registration.
@@ -2217,16 +2425,19 @@
   /// resource operations returned via the `CodeAction#edit` property by for
   /// example presenting the workspace edit in the user interface and asking for
   /// confirmation.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? honorsChangeAnnotations;
 
   /// Whether code action supports the `isPreferred` property.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? isPreferredSupport;
 
   /// Whether the client supports resolving additional code action properties
   /// via a separate `codeAction/resolve` request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final CodeActionClientCapabilitiesResolveSupport? resolveSupport;
 
   @override
@@ -2393,7 +2604,7 @@
     );
   }
 
-  /// The code action kind is supported with the following value set.
+  /// The code action kind is support with the following value set.
   final CodeActionLiteralSupportCodeActionKind codeActionKind;
 
   @override
@@ -2575,7 +2786,8 @@
   final List<CodeActionKind>? only;
 
   /// The reason why code actions were requested.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final CodeActionTriggerKind? triggerKind;
 
   @override
@@ -2738,7 +2950,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// A set of predefined code action kinds.
+/// A set of predefined code action kinds
 class CodeActionKind implements ToJsonable {
   const CodeActionKind(this._value);
   const CodeActionKind.fromJson(this._value);
@@ -2752,13 +2964,13 @@
   /// Empty kind.
   static const Empty = CodeActionKind('');
 
-  /// Base kind for quickfix actions: 'quickfix'.
+  /// Base kind for quickfix actions: 'quickfix'
   static const QuickFix = CodeActionKind('quickfix');
 
-  /// Base kind for refactoring actions: 'refactor'.
+  /// Base kind for refactoring actions: 'refactor'
   static const Refactor = CodeActionKind('refactor');
 
-  /// Base kind for refactoring extraction actions: 'refactor.extract'.
+  /// Base kind for refactoring extraction actions: 'refactor.extract'
   ///
   /// Example extract actions:
   ///
@@ -2769,7 +2981,7 @@
   /// - ...
   static const RefactorExtract = CodeActionKind('refactor.extract');
 
-  /// Base kind for refactoring inline actions: 'refactor.inline'.
+  /// Base kind for refactoring inline actions: 'refactor.inline'
   ///
   /// Example inline actions:
   ///
@@ -2779,7 +2991,7 @@
   /// - ...
   static const RefactorInline = CodeActionKind('refactor.inline');
 
-  /// Base kind for refactoring rewrite actions: 'refactor.rewrite'.
+  /// Base kind for refactoring rewrite actions: 'refactor.rewrite'
   ///
   /// Example rewrite actions:
   ///
@@ -2791,19 +3003,21 @@
   /// - ...
   static const RefactorRewrite = CodeActionKind('refactor.rewrite');
 
-  /// Base kind for source actions: `source`.
+  /// Base kind for source actions: `source`
   ///
   /// Source code actions apply to the entire file.
   static const Source = CodeActionKind('source');
 
-  /// Base kind for a 'fix all' source action: `source.fixAll`.
-  ///  'Fix all' actions automatically fix errors that have a clear fix that do
-  /// not require user input. They should not suppress errors or perform unsafe
+  /// Base kind for auto-fix source actions: `source.fixAll`.
+  ///
+  /// Fix all actions automatically fix errors that have a clear fix that do not
+  /// require user input. They should not suppress errors or perform unsafe
   /// fixes such as generating new types or classes.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.15.0
   static const SourceFixAll = CodeActionKind('source.fixAll');
 
-  /// Base kind for an organize imports source action: `source.organizeImports`.
+  /// Base kind for an organize imports source action: `source.organizeImports`
   static const SourceOrganizeImports = CodeActionKind('source.organizeImports');
 
   @override
@@ -2899,6 +3113,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a CodeActionRequest.
 class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeActionOptions.canParse,
@@ -2937,7 +3152,8 @@
 
   /// The server provides support to resolve additional information for a code
   /// action.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? resolveProvider;
   @override
   final bool? workDoneProgress;
@@ -3023,7 +3239,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Params for the CodeActionRequest
+/// The parameters of a CodeActionRequest.
 class CodeActionParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -3218,6 +3434,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a CodeActionRequest.
 class CodeActionRegistrationOptions
     implements CodeActionOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -3267,7 +3484,8 @@
 
   /// The server provides support to resolve additional information for a code
   /// action.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   @override
   final bool? resolveProvider;
   @override
@@ -3382,7 +3600,8 @@
 }
 
 /// The reason why code actions were requested.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class CodeActionTriggerKind implements ToJsonable {
   const CodeActionTriggerKind(this._value);
   const CodeActionTriggerKind.fromJson(this._value);
@@ -3417,7 +3636,8 @@
 }
 
 /// Structure to capture a description for an error code.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class CodeDescription implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeDescription.canParse,
@@ -3523,8 +3743,8 @@
   /// The command this code lens represents.
   final Command? command;
 
-  /// A data entry field that is preserved on a code lens item between a code
-  /// lens and a code lens resolve request.
+  /// A data entry field that is preserved on a code lens item between a
+  /// CodeLensRequest and a CodeLensResolveRequest
   final Object? data;
 
   /// The range in which this code lens is valid. Should only span a single
@@ -3603,6 +3823,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The client capabilities  of a CodeLensRequest.
 class CodeLensClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeLensClientCapabilities.canParse,
@@ -3667,6 +3888,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Code Lens provider options of a CodeLensRequest.
 class CodeLensOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeLensOptions.canParse,
@@ -3757,6 +3979,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a CodeLensRequest.
 class CodeLensParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -3894,6 +4117,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a CodeLensRequest.
 class CodeLensRegistrationOptions
     implements CodeLensOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -4022,6 +4246,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class CodeLensWorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CodeLensWorkspaceClientCapabilities.canParse,
@@ -4251,6 +4476,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents a color range from a document.
 class ColorInformation implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ColorInformation.canParse,
@@ -4378,9 +4604,9 @@
     );
   }
 
-  /// An optional array of additional text edits ([TextEdit]) that are applied
-  /// when selecting this color presentation. Edits must not overlap with the
-  /// main [edit](#ColorPresentation.textEdit) nor with themselves.
+  /// An optional array of additional text edits that are applied when selecting
+  /// this color presentation. Edits must not overlap with the main edit nor
+  /// with themselves.
   final List<TextEdit>? additionalTextEdits;
 
   /// The label of this color presentation. It will be shown on the color picker
@@ -4388,9 +4614,8 @@
   /// this color presentation.
   final String label;
 
-  /// An edit ([TextEdit]) which is applied to a document when selecting this
-  /// presentation for the color. When `falsy` the
-  /// [label](#ColorPresentation.label) is used.
+  /// An edit which is applied to a document when selecting this presentation
+  /// for the color.  When `falsy` the label is used.
   final TextEdit? textEdit;
 
   @override
@@ -4480,6 +4705,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a ColorPresentationRequest.
 class ColorPresentationParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -4527,7 +4753,7 @@
     );
   }
 
-  /// The color information to request presentations for.
+  /// The color to request presentations for.
   final Color color;
 
   /// An optional token that a server can use to report partial results (e.g.
@@ -4674,6 +4900,10 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents a reference to a command. Provides a title which will be used to
+/// represent a command in the UI and, optionally,
+/// an array of arguments which will be passed to the command handler function
+/// when invoked.
 class Command implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Command.canParse,
@@ -4799,6 +5029,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Completion client capabilities
 class CompletionClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CompletionClientCapabilities.canParse,
@@ -4852,7 +5083,8 @@
   final CompletionClientCapabilitiesCompletionItemKind? completionItemKind;
 
   /// The client supports the following `CompletionList` specific capabilities.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final CompletionClientCapabilitiesCompletionList? completionList;
 
   /// The client supports to send additional context information for a
@@ -4862,9 +5094,11 @@
   /// Whether completion supports dynamic registration.
   final bool? dynamicRegistration;
 
-  /// The client's default when the completion item doesn't provide a
-  /// `insertTextMode` property.
-  ///  @since 3.17.0
+  /// Defines how the client handles whitespace and indentation when accepting a
+  /// completion item that uses multi line text in either `insertText` or
+  /// `textEdit`.
+  ///
+  /// @since 3.17.0
   final InsertTextMode? insertTextMode;
 
   @override
@@ -5070,24 +5304,27 @@
   /// Client supports the deprecated property on a completion item.
   final bool? deprecatedSupport;
 
-  /// Client supports the follow content formats for the documentation property.
-  /// The order describes the preferred format of the client.
+  /// Client supports the following content formats for the documentation
+  /// property. The order describes the preferred format of the client.
   final List<MarkupKind>? documentationFormat;
 
-  /// Client supports insert replace edit to control different behavior if a
+  /// Client support insert replace edit to control different behavior if a
   /// completion item is inserted in the text or should replace text.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? insertReplaceSupport;
 
   /// The client supports the `insertTextMode` property on a completion item to
   /// override the whitespace handling mode as defined by the client (see
   /// `insertTextMode`).
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final CompletionItemInsertTextModeSupport? insertTextModeSupport;
 
   /// The client has support for completion item label details (see also
   /// `CompletionItemLabelDetails`).
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final bool? labelDetailsSupport;
 
   /// Client supports the preselect property on a completion item.
@@ -5095,23 +5332,25 @@
 
   /// Indicates which properties a client can resolve lazily on a completion
   /// item. Before version 3.16.0 only the predefined properties `documentation`
-  /// and `detail` could be resolved lazily.
-  ///  @since 3.16.0
+  /// and `details` could be resolved lazily.
+  ///
+  /// @since 3.16.0
   final CompletionItemResolveSupport? resolveSupport;
 
   /// Client supports snippets as insert text.
   ///
   /// A snippet can define tab stops and placeholders with `$1`, `$2` and
   /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the
-  /// snippet. Placeholders with equal identifiers are linked, that is typing in
-  /// one will update others too.
+  /// snippet. Placeholders with equal identifiers are linked,
+  /// that is typing in one will update others too.
   final bool? snippetSupport;
 
   /// Client supports the tag property on a completion item. Clients supporting
   /// tags have to handle unknown tags gracefully. Clients especially need to
   /// preserve unknown tags when sending a completion item back to the server in
   /// a resolve call.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final CompletionItemTagSupport? tagSupport;
 
   @override
@@ -5407,12 +5646,13 @@
     );
   }
 
-  /// The client supports the the following itemDefaults on a completion list.
+  /// The client supports the following itemDefaults on a completion list.
   ///
   /// The value lists the supported property names of the
   /// `CompletionList.itemDefaults` object. If omitted no properties are
   /// supported.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final List<String>? itemDefaults;
 
   @override
@@ -5561,6 +5801,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A completion item represents a text snippet that is proposed to complete
+/// text that is being typed.
 class CompletionItem implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CompletionItem.canParse,
@@ -5706,11 +5948,11 @@
   final List<String>? commitCharacters;
 
   /// A data entry field that is preserved on a completion item between a
-  /// completion and a completion resolve request.
+  /// CompletionRequest and a CompletionResolveRequest.
   final CompletionItemResolutionInfo? data;
 
   /// Indicates if this item is deprecated.
-  ///  @deprecated Use `tags` instead if supported.
+  /// @deprecated Use `tags` instead.
   final bool? deprecated;
 
   /// A human-readable string with additional information about this item, like
@@ -5721,12 +5963,11 @@
   final Either2<MarkupContent, String>? documentation;
 
   /// A string that should be used when filtering a set of completion items.
-  /// When `falsy` the label is used as the filter text for this item.
+  /// When `falsy` the label is used.
   final String? filterText;
 
   /// A string that should be inserted into a document when selecting this
-  /// completion. When `falsy` the label is used as the insert text for this
-  /// item.
+  /// completion. When `falsy` the label is used.
   ///
   /// The `insertText` is subject to interpretation by the client side. Some
   /// tools might not take the string literally. For example VS Code when code
@@ -5745,15 +5986,14 @@
   final InsertTextFormat? insertTextFormat;
 
   /// How whitespace and indentation is handled during completion item
-  /// insertion. If not provided the client's default value depends on the
+  /// insertion. If not provided the clients default value depends on the
   /// `textDocument.completion.insertTextMode` client capability.
-  ///  @since 3.16.0 @since 3.17.0 - support for
-  /// `textDocument.completion.insertTextMode`
+  ///
+  /// @since 3.16.0
   final InsertTextMode? insertTextMode;
 
   /// The kind of this completion item. Based of the kind an icon is chosen by
-  /// the editor. The standardized set of available values is defined in
-  /// `CompletionItemKind`.
+  /// the editor.
   final CompletionItemKind? kind;
 
   /// The label of this completion item.
@@ -5766,37 +6006,35 @@
   final String label;
 
   /// Additional details for the label
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final CompletionItemLabelDetails? labelDetails;
 
   /// Select this item when showing.
   ///
   /// *Note* that only one completion item can be selected and that the tool /
-  /// client decides which item that is. The rule is that the *first* item of
-  /// those that match best is selected.
+  /// client decides which item that is. The rule is that the *first*
+  /// item of those that match best is selected.
   final bool? preselect;
 
   /// A string that should be used when comparing this item with other items.
-  /// When `falsy` the label is used as the sort text for this item.
+  /// When `falsy` the label is used.
   final String? sortText;
 
   /// Tags for this completion item.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final List<CompletionItemTag>? tags;
 
   /// An edit which is applied to a document when selecting this completion.
-  /// When an edit is provided the value of `insertText` is ignored.
-  ///
-  /// *Note:* The range of the edit must be a single line range and it must
-  /// contain the position at which completion has been requested.
+  /// When an edit is provided the value of insertText is ignored.
   ///
   /// Most editors support two different operations when accepting a completion
   /// item. One is to insert a completion text and the other is to replace an
   /// existing text with a completion text. Since this can usually not be
   /// predetermined by a server it can report both ranges. Clients need to
-  /// signal support for `InsertReplaceEdit`s via the
-  /// `textDocument.completion.completionItem.insertReplaceSupport` client
-  /// capability property.
+  /// signal support for `InsertReplaceEdits` via the
+  /// `textDocument.completion.insertReplaceSupport` client capability property.
   ///
   /// *Note 1:* The text edit's range as well as both ranges from an insert
   /// replace edit must be a [single line] and they must contain the position at
@@ -5804,7 +6042,8 @@
   /// *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
   /// must be a prefix of the edit's replace range, that means it must be
   /// contained and starting at the same position.
-  ///  @since 3.16.0 additional type `InsertReplaceEdit`
+  ///
+  /// @since 3.16.0 additional type `InsertReplaceEdit`
   final Either2<InsertReplaceEdit, TextEdit>? textEdit;
 
   /// The edit text used if the completion item is part of a CompletionList and
@@ -5815,7 +6054,8 @@
   ///
   /// If not provided and a list's default range is provided the label property
   /// is used as a text.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final String? textEditText;
 
   @override
@@ -6386,7 +6626,8 @@
 }
 
 /// Additional details for a completion item label.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class CompletionItemLabelDetails implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CompletionItemLabelDetails.canParse,
@@ -6409,13 +6650,14 @@
   }
 
   /// An optional string which is rendered less prominently after {@link
-  /// CompletionItemLabelDetails.detail}. Should be used for fully qualified
-  /// names or file path.
+  /// CompletionItem.detail}. Should be used for fully qualified names and file
+  /// paths.
   final String? description;
 
   /// An optional string which is rendered less prominently directly after
-  /// {@link CompletionItem.label label}, without any spacing. Should be used
-  /// for function signatures or type annotations.
+  /// {@link CompletionItem.label label},
+  /// without any spacing. Should be used for function signatures and type
+  /// annotations.
   final String? detail;
 
   @override
@@ -6555,7 +6797,8 @@
 
 /// Completion item tags are extra annotations that tweak the rendering of a
 /// completion item.
-///  @since 3.15.0
+///
+/// @since 3.15.0
 class CompletionItemTag implements ToJsonable {
   const CompletionItemTag(this._value);
   const CompletionItemTag.fromJson(this._value);
@@ -6659,8 +6902,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Represents a collection of completion items ([CompletionItem]) to be
-/// presented in the editor.
+/// Represents a collection of completion items to be presented in the editor.
 class CompletionList implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CompletionList.canParse,
@@ -6691,8 +6933,8 @@
     );
   }
 
-  /// This list is not complete. Further typing should result in recomputing
-  /// this list.
+  /// This list it not complete. Further typing results in recomputing this
+  /// list.
   ///
   /// Recomputed lists have all their items replaced (not appended) in the
   /// incomplete completion sessions.
@@ -6708,7 +6950,8 @@
   ///
   /// Servers are only allowed to return default values if the client signals
   /// support for this via the `completionList.itemDefaults` capability.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final CompletionListItemDefaults? itemDefaults;
 
   /// The completion items.
@@ -6854,23 +7097,28 @@
   }
 
   /// A default commit character set.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final List<String>? commitCharacters;
 
   /// A default data value.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Object? data;
 
-  /// A default edit range
-  ///  @since 3.17.0
+  /// A default edit range.
+  ///
+  /// @since 3.17.0
   final Either2<CompletionItemEditRange, Range>? editRange;
 
-  /// A default insert text format
-  ///  @since 3.17.0
+  /// A default insert text format.
+  ///
+  /// @since 3.17.0
   final InsertTextFormat? insertTextFormat;
 
-  /// A default insert text mode
-  ///  @since 3.17.0
+  /// A default insert text mode.
+  ///
+  /// @since 3.17.0
   final InsertTextMode? insertTextMode;
 
   @override
@@ -7024,16 +7272,18 @@
 
   /// The list of all possible characters that commit a completion. This field
   /// can be used if clients don't support individual commit characters per
-  /// completion item. See client capability
-  /// `completion.completionItem.commitCharactersSupport`.
+  /// completion item. See
+  /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`
   ///
   /// If a server provides both `allCommitCharacters` and commit characters on
   /// an individual completion item the ones on the completion item win.
-  ///  @since 3.2.0
+  ///
+  /// @since 3.2.0
   final List<String>? allCommitCharacters;
 
   /// The server supports the following `CompletionItem` specific capabilities.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final CompletionOptionsCompletionItem? completionItem;
 
   /// The server provides support to resolve additional information for a
@@ -7189,7 +7439,8 @@
   /// The server has support for completion item label details (see also
   /// `CompletionItemLabelDetails`) when receiving a completion item in a
   /// resolve call.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final bool? labelDetailsSupport;
 
   @override
@@ -7236,6 +7487,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Completion parameters
 class CompletionParams
     implements
         PartialResultParams,
@@ -7289,8 +7541,9 @@
     );
   }
 
-  /// The completion context. This is only available if the client specifies to
-  /// send this using the client capability `completion.contextSupport === true`
+  /// The completion context. This is only available it the client specifies to
+  /// send this using the client capability
+  /// `textDocument.completion.contextSupport === true`
   final CompletionContext? context;
 
   /// An optional token that a server can use to report partial results (e.g.
@@ -7432,6 +7685,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a CompletionRequest.
 class CompletionRegistrationOptions
     implements CompletionOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -7482,17 +7736,19 @@
 
   /// The list of all possible characters that commit a completion. This field
   /// can be used if clients don't support individual commit characters per
-  /// completion item. See client capability
-  /// `completion.completionItem.commitCharactersSupport`.
+  /// completion item. See
+  /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`
   ///
   /// If a server provides both `allCommitCharacters` and commit characters on
   /// an individual completion item the ones on the completion item win.
-  ///  @since 3.2.0
+  ///
+  /// @since 3.2.0
   @override
   final List<String>? allCommitCharacters;
 
   /// The server supports the following `CompletionItem` specific capabilities.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   @override
   final CompletionOptionsCompletionItem? completionItem;
 
@@ -7688,7 +7944,7 @@
   /// `triggerCharacters` properties of the `CompletionRegistrationOptions`.
   static const TriggerCharacter = CompletionTriggerKind._(2);
 
-  /// Completion was re-triggered as the current completion list is incomplete.
+  /// Completion was re-triggered as current completion list is incomplete
   static const TriggerForIncompleteCompletions = CompletionTriggerKind._(3);
 
   @override
@@ -7791,6 +8047,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a configuration request.
 class ConfigurationParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ConfigurationParams.canParse,
@@ -7865,8 +8122,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Create file operation
-class CreateFile implements ToJsonable {
+/// Create file operation.
+class CreateFile implements ResourceOperation, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CreateFile.canParse,
     CreateFile.fromJson,
@@ -7902,10 +8159,13 @@
   }
 
   /// An optional annotation identifier describing the operation.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
+  @override
   final String? annotationId;
 
   /// A create
+  @override
   final String kind;
 
   /// Additional options
@@ -8108,7 +8368,8 @@
 
 /// The parameters sent in notifications/requests for user-initiated creation of
 /// files.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class CreateFilesParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CreateFilesParams.canParse,
@@ -8183,6 +8444,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.14.0
 class DeclarationClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DeclarationClientCapabilities.canParse,
@@ -8645,6 +8907,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client Capabilities for a DefinitionRequest.
 class DefinitionClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DefinitionClientCapabilities.canParse,
@@ -8670,7 +8933,8 @@
   final bool? dynamicRegistration;
 
   /// The client supports additional metadata in the form of definition links.
-  ///  @since 3.14.0
+  ///
+  /// @since 3.14.0
   final bool? linkSupport;
 
   @override
@@ -8735,6 +8999,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Server Capabilities for a DefinitionRequest.
 class DefinitionOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DefinitionOptions.canParse,
@@ -8801,6 +9066,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a DefinitionRequest.
 class DefinitionParams
     implements
         PartialResultParams,
@@ -8972,6 +9238,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DefinitionRequest.
 class DefinitionRegistrationOptions
     implements DefinitionOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -9078,7 +9345,7 @@
 }
 
 /// Delete file operation
-class DeleteFile implements ToJsonable {
+class DeleteFile implements ResourceOperation, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DeleteFile.canParse,
     DeleteFile.fromJson,
@@ -9114,10 +9381,13 @@
   }
 
   /// An optional annotation identifier describing the operation.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
+  @override
   final String? annotationId;
 
   /// A delete
+  @override
   final String kind;
 
   /// Delete options.
@@ -9320,7 +9590,8 @@
 
 /// The parameters sent in notifications/requests for user-initiated deletes of
 /// files.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class DeleteFilesParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DeleteFilesParams.canParse,
@@ -9395,6 +9666,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents a diagnostic, such as a compiler error or warning. Diagnostic
+/// objects are only valid in the scope of a resource.
 class Diagnostic implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Diagnostic.canParse,
@@ -9453,23 +9726,26 @@
     );
   }
 
-  /// The diagnostic's code, which might appear in the user interface.
+  /// The diagnostic's code, which usually appear in the user interface.
   final String? code;
 
-  /// An optional property to describe the error code.
-  ///  @since 3.16.0
+  /// An optional property to describe the error code. Requires the code field
+  /// (above) to be present/not null.
+  ///
+  /// @since 3.16.0
   final CodeDescription? codeDescription;
 
   /// A data entry field that is preserved between a
   /// `textDocument/publishDiagnostics` notification and
   /// `textDocument/codeAction` request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Object? data;
 
-  /// The diagnostic's message.
+  /// The diagnostic's message. It usually appears in the user interface
   final String message;
 
-  /// The range at which the message applies.
+  /// The range at which the message applies
   final Range range;
 
   /// An array of related diagnostic information, e.g. when symbol-names within
@@ -9481,11 +9757,12 @@
   final DiagnosticSeverity? severity;
 
   /// A human-readable string describing the source of this diagnostic, e.g.
-  /// 'typescript' or 'super lint'.
+  /// 'typescript' or 'super lint'. It usually appears in the user interface.
   final String? source;
 
   /// Additional metadata about the diagnostic.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final List<DiagnosticTag>? tags;
 
   @override
@@ -9672,7 +9949,8 @@
 }
 
 /// Client capabilities specific to diagnostic pull requests.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DiagnosticClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DiagnosticClientCapabilities.canParse,
@@ -9767,7 +10045,8 @@
 }
 
 /// Diagnostic options.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DiagnosticOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DiagnosticOptions.canParse,
@@ -9919,7 +10198,8 @@
 }
 
 /// Diagnostic registration options.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DiagnosticRegistrationOptions
     implements
         DiagnosticOptions,
@@ -10139,7 +10419,7 @@
 }
 
 /// Represents a related message and source code location for a diagnostic. This
-/// should be used to point to code locations that cause or are related to a
+/// should be used to point to code locations that cause or related to a
 /// diagnostics, e.g when duplicating a symbol in a scope.
 class DiagnosticRelatedInformation implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -10241,7 +10521,8 @@
 }
 
 /// Cancellation data returned from a diagnostic request.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DiagnosticServerCancellationData implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DiagnosticServerCancellationData.canParse,
@@ -10311,6 +10592,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The diagnostic's severity.
 class DiagnosticSeverity implements ToJsonable {
   const DiagnosticSeverity(this._value);
   const DiagnosticSeverity.fromJson(this._value);
@@ -10348,7 +10630,8 @@
 }
 
 /// The diagnostic tags.
-///  @since 3.15.0
+///
+/// @since 3.15.0
 class DiagnosticTag implements ToJsonable {
   const DiagnosticTag(this._value);
   const DiagnosticTag.fromJson(this._value);
@@ -10385,7 +10668,8 @@
 }
 
 /// Workspace client capabilities specific to diagnostic pull requests.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DiagnosticWorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DiagnosticWorkspaceClientCapabilities.canParse,
@@ -10524,6 +10808,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a change configuration notification.
 class DidChangeConfigurationParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeConfigurationParams.canParse,
@@ -10577,7 +10862,8 @@
 }
 
 /// The params sent in a change notebook document notification.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DidChangeNotebookDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeNotebookDocumentParams.canParse,
@@ -10603,19 +10889,25 @@
 
   /// The actual changes to the notebook document.
   ///
-  /// The change describes single state change to the notebook document. So it
-  /// moves a notebook document, its cells and its cell text document contents
-  /// from state S to S'.
+  /// The changes describe single state changes to the notebook document. So if
+  /// there are two changes c1 (at array index 0) and c2 (at array index 1) for
+  /// a notebook in state S then c1 moves the notebook from S to S' and c2 from
+  /// S' to S''. So c1 is computed on the state S and c2 is computed on the
+  /// state S'.
   ///
   /// To mirror the content of a notebook using change events use the following
   /// approach:
   /// - start with the same initial content
-  /// - apply the 'notebookDocument/didChange' notifications in the order
+  /// - apply the 'notebookDocument/didChange' notifications in the order you
+  /// receive them.
+  /// - apply the `NotebookChangeEvent`s in a single notification in the order
   ///   you receive them.
   final NotebookDocumentChangeEvent change;
 
   /// The notebook document that did change. The version number points to the
-  /// version after all provided changes have been applied.
+  /// version after all provided changes have been applied. If only the text
+  /// document content of a cell changes the notebook version doesn't
+  /// necessarily have to change.
   final VersionedNotebookDocumentIdentifier notebookDocument;
 
   @override
@@ -10694,6 +10986,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The change text document notification's parameters.
 class DidChangeTextDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeTextDocumentParams.canParse,
@@ -10737,9 +11030,10 @@
   /// approach:
   /// - start with the same initial content
   /// - apply the 'textDocument/didChange' notifications in the order you
-  ///   receive them.
-  /// - apply the `TextDocumentContentChangeEvent`s in a single notification
-  ///   in the order you receive them.
+  /// receive them.
+  /// - apply the `TextDocumentContentChangeEvent`s in a single notification in
+  /// the order
+  ///   you receive them.
   final List<
       Either2<TextDocumentContentChangeEvent1,
           TextDocumentContentChangeEvent2>> contentChanges;
@@ -10863,8 +11157,11 @@
   /// for file changes from the server side.
   final bool? dynamicRegistration;
 
-  /// Whether the client has support for relative patterns or not.
-  ///  @since 3.17.0
+  /// Whether the client has support for {@link  RelativePattern relative
+  /// pattern}
+  /// or not.
+  ///
+  /// @since 3.17.0
   final bool? relativePatternSupport;
 
   @override
@@ -10930,6 +11227,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The watched files change notification's parameters.
 class DidChangeWatchedFilesParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeWatchedFilesParams.canParse,
@@ -11005,7 +11303,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Describe options to be used when registering for file system change events.
+/// Describe options to be used when registered for text document change events.
 class DidChangeWatchedFilesRegistrationOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeWatchedFilesRegistrationOptions.canParse,
@@ -11084,6 +11382,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a `workspace/didChangeWorkspaceFolders` notification.
 class DidChangeWorkspaceFoldersParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidChangeWorkspaceFoldersParams.canParse,
@@ -11156,7 +11455,8 @@
 }
 
 /// The params sent in a close notebook document notification.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DidCloseNotebookDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidCloseNotebookDocumentParams.canParse,
@@ -11267,6 +11567,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters sent in a close text document notification
 class DidCloseTextDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidCloseTextDocumentParams.canParse,
@@ -11338,8 +11639,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// The params sent in a open notebook document notification.
-///  @since 3.17.0
+/// The params sent in an open notebook document notification.
+///
+/// @since 3.17.0
 class DidOpenNotebookDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidOpenNotebookDocumentParams.canParse,
@@ -11448,6 +11750,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters sent in an open text document notification
 class DidOpenTextDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidOpenTextDocumentParams.canParse,
@@ -11520,7 +11823,8 @@
 }
 
 /// The params sent in a save notebook document notification.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DidSaveNotebookDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidSaveNotebookDocumentParams.canParse,
@@ -11592,6 +11896,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters sent in a save text document notification
 class DidSaveTextDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DidSaveTextDocumentParams.canParse,
@@ -11704,7 +12009,9 @@
     );
   }
 
-  /// Whether document color supports dynamic registration.
+  /// Whether implementation supports dynamic registration. If this is set to
+  /// `true` the client supports the new `DocumentColorRegistrationOptions`
+  /// return value for the corresponding server capability as well.
   final bool? dynamicRegistration;
 
   @override
@@ -11818,6 +12125,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a DocumentColorRequest.
 class DocumentColorParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -12090,7 +12398,8 @@
 }
 
 /// Parameters of the document diagnostic request.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DocumentDiagnosticParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -12273,40 +12582,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// The document diagnostic report kinds.
-///  @since 3.17.0
-class DocumentDiagnosticReportKind implements ToJsonable {
-  const DocumentDiagnosticReportKind(this._value);
-  const DocumentDiagnosticReportKind.fromJson(this._value);
-
-  final String _value;
-
-  static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is String;
-  }
-
-  /// A diagnostic report with a full set of problems.
-  static const Full = DocumentDiagnosticReportKind('full');
-
-  /// A report indicating that the last returned report is still accurate.
-  static const Unchanged = DocumentDiagnosticReportKind('unchanged');
-
-  @override
-  Object toJson() => _value;
-
-  @override
-  String toString() => _value.toString();
-
-  @override
-  int get hashCode => _value.hashCode;
-
-  @override
-  bool operator ==(Object other) =>
-      other is DocumentDiagnosticReportKind && other._value == _value;
-}
-
 /// A partial result for a document diagnostic report.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class DocumentDiagnosticReportPartialResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentDiagnosticReportPartialResult.canParse,
@@ -12410,6 +12688,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client capabilities of a DocumentFormattingRequest.
 class DocumentFormattingClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentFormattingClientCapabilities.canParse,
@@ -12476,6 +12755,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a DocumentFormattingRequest.
 class DocumentFormattingOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentFormattingOptions.canParse,
@@ -12544,6 +12824,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a DocumentFormattingRequest.
 class DocumentFormattingParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentFormattingParams.canParse,
@@ -12678,6 +12959,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentFormattingRequest.
 class DocumentFormattingRegistrationOptions
     implements
         DocumentFormattingOptions,
@@ -12814,7 +13096,7 @@
     );
   }
 
-  /// The highlight kind, default is DocumentHighlightKind.Text.
+  /// The highlight kind, default is text.
   final DocumentHighlightKind? kind;
 
   /// The range this highlight applies to.
@@ -12885,6 +13167,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client Capabilities for a DocumentHighlightRequest.
 class DocumentHighlightClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentHighlightClientCapabilities.canParse,
@@ -12985,6 +13268,7 @@
       other is DocumentHighlightKind && other._value == _value;
 }
 
+/// Provider options for a DocumentHighlightRequest.
 class DocumentHighlightOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentHighlightOptions.canParse,
@@ -13053,6 +13337,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a DocumentHighlightRequest.
 class DocumentHighlightParams
     implements
         PartialResultParams,
@@ -13225,6 +13510,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentHighlightRequest.
 class DocumentHighlightRegistrationOptions
     implements
         DocumentHighlightOptions,
@@ -13380,9 +13666,10 @@
   ///
   /// If a tooltip is provided, is will be displayed in a string that includes
   /// instructions on how to trigger the link, such as `{0} (ctrl + click)`. The
-  /// specific instructions vary depending on OS, user settings, and
-  /// localization.
-  ///  @since 3.15.0
+  /// specific instructions vary depending on OS,
+  /// user settings, and localization.
+  ///
+  /// @since 3.15.0
   final String? tooltip;
 
   @override
@@ -13472,6 +13759,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The client capabilities of a DocumentLinkRequest.
 class DocumentLinkClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentLinkClientCapabilities.canParse,
@@ -13497,7 +13785,8 @@
   final bool? dynamicRegistration;
 
   /// Whether the client supports the `tooltip` property on `DocumentLink`.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? tooltipSupport;
 
   @override
@@ -13562,6 +13851,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a DocumentLinkRequest.
 class DocumentLinkOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentLinkOptions.canParse,
@@ -13653,6 +13943,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a DocumentLinkRequest.
 class DocumentLinkParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -13791,6 +14082,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentLinkRequest.
 class DocumentLinkRegistrationOptions
     implements
         DocumentLinkOptions,
@@ -13922,6 +14214,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client capabilities of a DocumentOnTypeFormattingRequest.
 class DocumentOnTypeFormattingClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentOnTypeFormattingClientCapabilities.canParse,
@@ -13988,6 +14281,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a DocumentOnTypeFormattingRequest.
 class DocumentOnTypeFormattingOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentOnTypeFormattingOptions.canParse,
@@ -14092,6 +14386,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a DocumentOnTypeFormattingRequest.
 class DocumentOnTypeFormattingParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentOnTypeFormattingParams.canParse,
@@ -14256,6 +14551,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentOnTypeFormattingRequest.
 class DocumentOnTypeFormattingRegistrationOptions
     implements
         DocumentOnTypeFormattingOptions,
@@ -14402,6 +14698,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client capabilities of a DocumentRangeFormattingRequest.
 class DocumentRangeFormattingClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentRangeFormattingClientCapabilities.canParse,
@@ -14420,7 +14717,7 @@
     );
   }
 
-  /// Whether formatting supports dynamic registration.
+  /// Whether range formatting supports dynamic registration.
   final bool? dynamicRegistration;
 
   @override
@@ -14468,6 +14765,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a DocumentRangeFormattingRequest.
 class DocumentRangeFormattingOptions
     implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -14537,6 +14835,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a DocumentRangeFormattingRequest.
 class DocumentRangeFormattingParams
     implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -14700,6 +14999,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentRangeFormattingRequest.
 class DocumentRangeFormattingRegistrationOptions
     implements
         DocumentRangeFormattingOptions,
@@ -14868,7 +15168,8 @@
   final List<DocumentSymbol>? children;
 
   /// Indicates if this symbol is deprecated.
-  ///  @deprecated Use tags instead
+  ///
+  /// @deprecated Use tags instead
   final bool? deprecated;
 
   /// More detail for this symbol, e.g the signature of a function.
@@ -14889,11 +15190,12 @@
   final Range range;
 
   /// The range that should be selected and revealed when this symbol is being
-  /// picked, e.g. the name of a function. Must be contained by the `range`.
+  /// picked, e.g the name of a function. Must be contained by the `range`.
   final Range selectionRange;
 
   /// Tags for this document symbol.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final List<SymbolTag>? tags;
 
   @override
@@ -15077,6 +15379,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client Capabilities for a DocumentSymbolRequest.
 class DocumentSymbolClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentSymbolClientCapabilities.canParse,
@@ -15126,7 +15429,8 @@
 
   /// The client supports an additional label presented in the UI when
   /// registering a document symbol provider.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? labelSupport;
 
   /// Specific capabilities for the `SymbolKind` in the
@@ -15136,7 +15440,8 @@
   /// The client supports tags on `SymbolInformation`. Tags are supported on
   /// `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
   /// Clients supporting tags have to handle unknown tags gracefully.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final DocumentSymbolClientCapabilitiesTagSupport? tagSupport;
 
   @override
@@ -15410,6 +15715,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a DocumentSymbolRequest.
 class DocumentSymbolOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     DocumentSymbolOptions.canParse,
@@ -15436,7 +15742,8 @@
 
   /// A human-readable string that is shown when multiple outlines trees are
   /// shown for the same document.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final String? label;
   @override
   final bool? workDoneProgress;
@@ -15503,6 +15810,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a DocumentSymbolRequest.
 class DocumentSymbolParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -15641,6 +15949,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a DocumentSymbolRequest.
 class DocumentSymbolRegistrationOptions
     implements
         DocumentSymbolOptions,
@@ -15680,7 +15989,8 @@
 
   /// A human-readable string that is shown when multiple outlines trees are
   /// shown for the same document.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   @override
   final String? label;
   @override
@@ -15774,6 +16084,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Predefined error codes.
 class ErrorCodes implements ToJsonable {
   const ErrorCodes(this._value);
   const ErrorCodes.fromJson(this._value);
@@ -15796,30 +16107,32 @@
   static const InvalidParams = ErrorCodes(-32602);
   static const InvalidRequest = ErrorCodes(-32600);
 
-  /// This is the end range of JSON-RPC reserved error codes. It doesn't denote
+  /// This is the end range of JSON RPC reserved error codes. It doesn't denote
   /// a real error code.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   static const jsonrpcReservedErrorRangeEnd = ErrorCodes(-32000);
 
-  /// This is the start range of JSON-RPC reserved error codes. It doesn't
-  /// denote a real error code. No LSP error codes should be defined between the
-  /// start and end range. For backwards compatibility the
+  /// This is the start range of JSON RPC reserved error codes. It doesn't
+  /// denote a real error code. No application error codes should be defined
+  /// between the start and end range. For backwards compatibility the
   /// `ServerNotInitialized` and the `UnknownErrorCode` are left in the range.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   static const jsonrpcReservedErrorRangeStart = ErrorCodes(-32099);
 
   /// This is the end range of LSP reserved error codes. It doesn't denote a
   /// real error code.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   static const lspReservedErrorRangeEnd = ErrorCodes(-32800);
 
   /// This is the start range of LSP reserved error codes. It doesn't denote a
   /// real error code.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   static const lspReservedErrorRangeStart = ErrorCodes(-32899);
   static const MethodNotFound = ErrorCodes(-32601);
-
-  /// Defined by JSON-RPC
   static const ParseError = ErrorCodes(-32700);
 
   /// The client has canceled a request and a server as detected the cancel.
@@ -15828,12 +16141,14 @@
   /// A request failed but it was syntactically correct, e.g the method name was
   /// known and the parameters were valid. The error message should contain
   /// human readable information about why the request failed.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   static const RequestFailed = ErrorCodes(-32803);
 
   /// The server cancelled the request. This error code should only be used for
   /// requests that explicitly support being server cancellable.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   static const ServerCancelled = ErrorCodes(-32802);
 
   /// Error code indicating that a server received a notification or request
@@ -15855,6 +16170,7 @@
       other is ErrorCodes && other._value == _value;
 }
 
+/// The client capabilities of a ExecuteCommandRequest.
 class ExecuteCommandClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ExecuteCommandClientCapabilities.canParse,
@@ -15919,6 +16235,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The server capabilities of a ExecuteCommandRequest.
 class ExecuteCommandOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ExecuteCommandOptions.canParse,
@@ -16019,6 +16336,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a ExecuteCommandRequest.
 class ExecuteCommandParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ExecuteCommandParams.canParse,
@@ -16148,7 +16466,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Execute command registration options.
+/// Registration options for a ExecuteCommandRequest.
 class ExecuteCommandRegistrationOptions
     implements ExecuteCommandOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -16393,7 +16711,7 @@
       other is FailureHandlingKind && other._value == _value;
 }
 
-/// The file event type.
+/// The file event type
 class FileChangeType implements ToJsonable {
   const FileChangeType(this._value);
   const FileChangeType.fromJson(this._value);
@@ -16428,7 +16746,8 @@
 }
 
 /// Represents information on a file/folder create.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileCreate implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileCreate.canParse,
@@ -16499,7 +16818,8 @@
 }
 
 /// Represents information on a file/folder delete.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileDelete implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileDelete.canParse,
@@ -16582,7 +16902,7 @@
   });
   static FileEvent fromJson(Map<String, Object?> json) {
     final typeJson = json['type'];
-    final type = typeJson as int;
+    final type = FileChangeType.fromJson(typeJson as int);
     final uriJson = json['uri'];
     final uri = uriJson as String;
     return FileEvent(
@@ -16592,15 +16912,15 @@
   }
 
   /// The change type.
-  final int type;
+  final FileChangeType type;
 
-  /// The file's URI.
+  /// The file's uri.
   final String uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['type'] = type;
+    result['type'] = type.toJson();
     result['uri'] = uri;
     return result;
   }
@@ -16618,8 +16938,8 @@
           reporter.reportError('must not be null');
           return false;
         }
-        if (type is! int) {
-          reporter.reportError('must be of type int');
+        if (!FileChangeType.canParse(type, reporter)) {
+          reporter.reportError('must be of type FileChangeType');
           return false;
         }
       } finally {
@@ -16668,6 +16988,13 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Capabilities relating to events from file operations by the user in the
+/// client.
+///
+/// These events do not come from the file system, they come from user
+/// operations like renaming a file in the UI.
+///
+/// @since 3.16.0
 class FileOperationClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationClientCapabilities.canParse,
@@ -16869,8 +17196,9 @@
 }
 
 /// A filter to describe in which file operation requests or notifications the
-/// server is interested in.
-///  @since 3.16.0
+/// server is interested in receiving.
+///
+/// @since 3.16.0
 class FileOperationFilter implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationFilter.canParse,
@@ -16896,7 +17224,7 @@
   /// The actual file operation pattern.
   final FileOperationPattern pattern;
 
-  /// A Uri like `file` or `untitled`.
+  /// A Uri scheme like `file` or `untitled`.
   final String? scheme;
 
   @override
@@ -16965,6 +17293,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Options for notifications/requests for user operations on files.
+///
+/// @since 3.16.0
 class FileOperationOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationOptions.canParse,
@@ -17173,8 +17504,9 @@
 }
 
 /// A pattern to describe in which file operation requests or notifications the
-/// server is interested in.
-///  @since 3.16.0
+/// server is interested in receiving.
+///
+/// @since 3.16.0
 class FileOperationPattern implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationPattern.canParse,
@@ -17210,12 +17542,12 @@
   /// - `?` 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`, …)
+  /// 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`)
+  /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not
+  /// `example.0`)
   final String glob;
 
   /// Whether to match files or folders with this pattern.
@@ -17312,7 +17644,8 @@
 }
 
 /// A pattern kind describing if a glob pattern matches a file a folder or both.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileOperationPatternKind implements ToJsonable {
   const FileOperationPatternKind(this._value);
   const FileOperationPatternKind.fromJson(this._value);
@@ -17344,7 +17677,8 @@
 }
 
 /// Matching options for the file operation pattern.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileOperationPatternOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationPatternOptions.canParse,
@@ -17410,7 +17744,8 @@
 }
 
 /// The options to register for file operations.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileOperationRegistrationOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileOperationRegistrationOptions.canParse,
@@ -17489,7 +17824,8 @@
 }
 
 /// Represents information on a file/folder rename.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class FileRename implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FileRename.canParse,
@@ -17616,7 +17952,8 @@
 
   /// The glob pattern to watch. See {@link GlobPattern glob pattern} for more
   /// detail.
-  ///  @since 3.17.0 support for relative patterns.
+  ///
+  /// @since 3.17.0 support for relative patterns.
   final Either2<String, RelativePattern> globPattern;
 
   /// The kind of events of interest. If omitted it defaults to WatchKind.Create
@@ -17734,7 +18071,8 @@
   /// The text that the client should show when the specified range is
   /// collapsed. If not defined or not supported by the client, a default will
   /// be chosen by the client.
-  ///  @since 3.17.0 - proposed
+  ///
+  /// @since 3.17.0
   final String? collapsedText;
 
   /// The zero-based character offset before the folded range ends. If not
@@ -17746,9 +18084,9 @@
   /// smaller than the number of lines in the document.
   final int endLine;
 
-  /// Describes the kind of the folding range such as `comment` or `region`. The
+  /// Describes the kind of the folding range such as `comment' or 'region'. The
   /// kind is used to categorize folding ranges and used by commands like 'Fold
-  /// all comments'. See [FoldingRangeKind] for an enumeration of standardized
+  /// all comments'. See FoldingRangeKind for an enumeration of standardized
   /// kinds.
   final FoldingRangeKind? kind;
 
@@ -17939,11 +18277,14 @@
   /// server capability as well.
   final bool? dynamicRegistration;
 
-  /// Specific options for the folding range. @since 3.17.0
+  /// Specific options for the folding range.
+  ///
+  /// @since 3.17.0
   final FoldingRangeClientCapabilitiesFoldingRange? foldingRange;
 
   /// Specific options for the folding range kind.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final FoldingRangeClientCapabilitiesFoldingRangeKind? foldingRangeKind;
 
   /// If set, the client signals that it only supports folding complete lines.
@@ -18089,7 +18430,8 @@
 
   /// If set, the client signals that it supports setting collapsedText on
   /// folding ranges to display custom labels instead of the default text.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final bool? collapsedText;
 
   @override
@@ -18226,7 +18568,7 @@
   /// Folding range for a comment
   static const Comment = FoldingRangeKind('comment');
 
-  /// Folding range for a imports or includes
+  /// Folding range for an import or include
   static const Imports = FoldingRangeKind('imports');
 
   /// Folding range for a region (e.g. `#region`)
@@ -18313,6 +18655,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a FoldingRangeRequest.
 class FoldingRangeParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -18619,7 +18962,8 @@
   }
 
   /// Insert a newline character at the end of the file if one does not exist.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? insertFinalNewline;
 
   /// Prefer spaces over tabs.
@@ -18629,11 +18973,13 @@
   final int tabSize;
 
   /// Trim all newlines after the final newline at the end of the file.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? trimFinalNewlines;
 
   /// Trim trailing whitespace on a line.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? trimTrailingWhitespace;
 
   @override
@@ -18755,7 +19101,8 @@
 }
 
 /// A diagnostic report with a full set of problems.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class FullDocumentDiagnosticReport implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     FullDocumentDiagnosticReport.canParse,
@@ -18896,6 +19243,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// General client capabilities.
+///
+/// @since 3.16.0
 class GeneralClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     GeneralClientCapabilities.canParse,
@@ -18937,12 +19287,13 @@
   }
 
   /// Client capabilities specific to the client's markdown parser.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final MarkdownClientCapabilities? markdown;
 
   /// The position encodings supported by the client. Client and server have to
   /// agree on the same position encoding to ensure that offsets (e.g. character
-  /// position in a line) are interpreted the same on both side.
+  /// position in a line) are interpreted the same on both sides.
   ///
   /// To keep the protocol backwards compatible the following applies: if the
   /// value 'utf-16' is missing from the array of position encodings servers can
@@ -18954,17 +19305,20 @@
   /// Implementation considerations: since the conversion from one encoding into
   /// another requires the content of the file / line the conversion is best
   /// done where the file is read which is usually on the server side.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final List<PositionEncodingKind>? positionEncodings;
 
   /// Client capabilities specific to regular expressions.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final RegularExpressionsClientCapabilities? regularExpressions;
 
   /// Client capability that signals how the client handles stale requests (e.g.
   /// a request for which the client will not process the response anymore since
   /// the information is outdated).
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final GeneralClientCapabilitiesStaleRequestSupport? staleRequestSupport;
 
   @override
@@ -19099,7 +19453,7 @@
   final bool cancel;
 
   /// The list of requests for which the client will retry the request if it
-  /// receives a response with error code `ContentModified``
+  /// receives a response with error code `ContentModified`
   final List<String> retryOnContentModified;
 
   @override
@@ -19211,8 +19565,8 @@
   /// The hover's content
   final Either2<MarkupContent, String> contents;
 
-  /// An optional range is a range inside a text document that is used to
-  /// visualize a hover, e.g. by changing the background color.
+  /// An optional range inside the text document that is used to visualize the
+  /// hover, e.g. by changing the background color.
   final Range? range;
 
   @override
@@ -19305,9 +19659,8 @@
     );
   }
 
-  /// Client supports the follow content formats if the content property refers
-  /// to a `literal of type MarkupContent`. The order describes the preferred
-  /// format of the client.
+  /// Client supports the following content formats for the content property.
+  /// The order describes the preferred format of the client.
   final List<MarkupKind>? contentFormat;
 
   /// Whether hover supports dynamic registration.
@@ -19380,6 +19733,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Hover options.
 class HoverOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     HoverOptions.canParse,
@@ -19446,6 +19800,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a HoverRequest.
 class HoverParams
     implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -19581,6 +19936,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a HoverRequest.
 class HoverRegistrationOptions
     implements HoverOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -19686,6 +20042,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.6.0
 class ImplementationClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ImplementationClientCapabilities.canParse,
@@ -19713,7 +20070,8 @@
   final bool? dynamicRegistration;
 
   /// The client supports additional metadata in the form of definition links.
-  ///  @since 3.14.0
+  ///
+  /// @since 3.14.0
   final bool? linkSupport;
 
   @override
@@ -20150,6 +20508,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The initialize parameters
 class InitializeParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InitializeParams.canParse,
@@ -20188,9 +20547,10 @@
     final rootUriJson = json['rootUri'];
     final rootUri = rootUriJson as String?;
     final traceJson = json['trace'];
-    final trace = const {null, 'off', 'messages', 'verbose'}.contains(traceJson)
+    final trace = const {null, 'off', 'messages', 'compact', 'verbose'}
+            .contains(traceJson)
         ? traceJson as String?
-        : throw '''$traceJson was not one of (null, 'off', 'messages', 'verbose')''';
+        : throw '''$traceJson was not one of (null, 'off', 'messages', 'compact', 'verbose')''';
     final workDoneTokenJson = json['workDoneToken'];
     final workDoneToken = workDoneTokenJson == null
         ? null
@@ -20221,7 +20581,8 @@
   final ClientCapabilities capabilities;
 
   /// Information about the client
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final InitializeParamsClientInfo? clientInfo;
 
   /// User provided initialization options.
@@ -20232,22 +20593,25 @@
   ///
   /// Uses IETF language tags as the value's syntax (See
   /// https://en.wikipedia.org/wiki/IETF_language_tag)
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final String? locale;
 
-  /// The process Id of the parent process that started the server. Is null if
-  /// the process has not been started by another process. If the parent process
-  /// is not alive then the server should exit (see exit notification) its
-  /// process.
+  /// The process Id of the parent process that started the server.
+  ///
+  /// Is `null` if the process has not been started by another process. If the
+  /// parent process is not alive then the server should exit.
   final int? processId;
 
   /// The rootPath of the workspace. Is null if no folder is open.
-  ///  @deprecated in favour of `rootUri`.
+  ///
+  /// @deprecated in favour of rootUri.
   final String? rootPath;
 
   /// The rootUri of the workspace. Is null if no folder is open. If both
   /// `rootPath` and `rootUri` are set `rootUri` wins.
-  ///  @deprecated in favour of `workspaceFolders`
+  ///
+  /// @deprecated in favour of workspaceFolders.
   final String? rootUri;
 
   /// The initial trace setting. If omitted trace is disabled ('off').
@@ -20258,10 +20622,12 @@
   final Either2<int, String>? workDoneToken;
 
   /// The workspace folders configured in the client when the server starts.
+  ///
   /// This property is only available if the client supports workspace folders.
   /// It can be `null` if the client supports workspace folders but none are
   /// configured.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final List<WorkspaceFolder>? workspaceFolders;
 
   @override
@@ -20380,9 +20746,10 @@
         if (trace != null &&
             trace != 'off' &&
             trace != 'messages' &&
+            trace != 'compact' &&
             trace != 'verbose') {
           reporter.reportError(
-              'must be one of the literals \'off\', \'messages\', \'verbose\'');
+              'must be one of the literals \'off\', \'messages\', \'compact\', \'verbose\'');
           return false;
         }
       } finally {
@@ -20550,6 +20917,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The result returned from an initialize request.
 class InitializeResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InitializeResult.canParse,
@@ -20579,7 +20947,8 @@
   final ServerCapabilities capabilities;
 
   /// Information about the server.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final InitializeResultServerInfo? serverInfo;
 
   @override
@@ -20781,7 +21150,8 @@
 }
 
 /// Inlay hint information.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHint implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHint.canParse,
@@ -20846,7 +21216,7 @@
     );
   }
 
-  /// A data entry field that is preserved on a inlay hint between a
+  /// A data entry field that is preserved on an inlay hint between a
   /// `textDocument/inlayHint` and a `inlayHint/resolve` request.
   final Object? data;
 
@@ -20882,15 +21252,9 @@
   /// *Note* that edits are expected to change the document so that the inlay
   /// hint (or its nearest variant) is now part of the document and the inlay
   /// hint itself is now obsolete.
-  ///
-  /// Depending on the client capability `inlayHint.resolveSupport` clients
-  /// might resolve this property late using the resolve request.
   final List<TextEdit>? textEdits;
 
   /// The tooltip text when you hover over this item.
-  ///
-  /// Depending on the client capability `inlayHint.resolveSupport` clients
-  /// might resolve this property late using the resolve request.
   final Either2<MarkupContent, String>? tooltip;
 
   @override
@@ -21056,7 +21420,8 @@
 }
 
 /// Inlay hint client capabilities.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHintClientCapabilities.canParse,
@@ -21084,7 +21449,7 @@
   /// Whether inlay hints support dynamic registration.
   final bool? dynamicRegistration;
 
-  /// Indicates which properties a client can resolve lazily on a inlay hint.
+  /// Indicates which properties a client can resolve lazily on an inlay hint.
   final InlayHintClientCapabilitiesResolveSupport? resolveSupport;
 
   @override
@@ -21230,7 +21595,8 @@
 }
 
 /// Inlay hint kinds.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintKind implements ToJsonable {
   const InlayHintKind(this._value);
   const InlayHintKind.fromJson(this._value);
@@ -21263,7 +21629,8 @@
 
 /// An inlay hint label part allows for interactive and composite labels of
 /// inlay hints.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintLabelPart implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHintLabelPart.canParse,
@@ -21315,8 +21682,8 @@
   /// The editor will use this location for the hover and for code navigation
   /// features: This part will become a clickable link that resolves to the
   /// definition of the symbol at the given location (not necessarily the
-  /// location itself), it shows the hover that shows at the given location, and
-  /// it shows a context menu with further code navigation commands.
+  /// location itself), it shows the hover that shows at the given location,
+  /// and it shows a context menu with further code navigation commands.
   ///
   /// Depending on the client capability `inlayHint.resolveSupport` clients
   /// might resolve this property late using the resolve request.
@@ -21432,7 +21799,8 @@
 }
 
 /// Inlay hint options used during static registration.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHintOptions.canParse,
@@ -21525,7 +21893,8 @@
 }
 
 /// A parameter literal used in inlay hint requests.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHintParams.canParse,
@@ -21558,7 +21927,7 @@
     );
   }
 
-  /// The visible document range for which inlay hints should be computed.
+  /// The document range for which inlay hints should be computed.
   final Range range;
 
   /// The text document.
@@ -21659,7 +22028,8 @@
 }
 
 /// Inlay hint options used during static or dynamic registration.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintRegistrationOptions
     implements
         InlayHintOptions,
@@ -21818,7 +22188,8 @@
 }
 
 /// Client workspace capabilities specific to inlay hints.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlayHintWorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlayHintWorkspaceClientCapabilities.canParse,
@@ -21892,7 +22263,8 @@
 }
 
 /// Client capabilities specific to inline values.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueClientCapabilities.canParse,
@@ -22062,13 +22434,11 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Provide an inline value through an expression evaluation.
+/// Provide an inline value through an expression evaluation. If only a range is
+/// specified, the expression will be extracted from the underlying document. An
+/// optional expression can be used to override the extracted expression.
 ///
-/// If only a range is specified, the expression will be extracted from the
-/// underlying document.
-///
-/// An optional expression can be used to override the extracted expression.
-///  @since 3.17.0
+/// @since 3.17.0
 class InlineValueEvaluatableExpression implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueEvaluatableExpression.canParse,
@@ -22164,7 +22534,8 @@
 }
 
 /// Inline value options used during static registration.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueOptions.canParse,
@@ -22233,7 +22604,8 @@
 }
 
 /// A parameter literal used in inline value requests.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueParams.canParse,
@@ -22397,7 +22769,8 @@
 }
 
 /// Inline value options used during static or dynamic registration.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueRegistrationOptions
     implements
         InlineValueOptions,
@@ -22532,7 +22905,8 @@
 }
 
 /// Provide inline value as text.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueText implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueText.canParse,
@@ -22631,13 +23005,11 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Provide inline value through a variable lookup.
-///
-/// If only a range is specified, the variable name will be extracted from the
-/// underlying document.
-///
+/// Provide inline value through a variable lookup. If only a range is
+/// specified, the variable name will be extracted from the underlying document.
 /// An optional variable name can be used to override the extracted name.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueVariableLookup implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueVariableLookup.canParse,
@@ -22763,7 +23135,8 @@
 }
 
 /// Client workspace capabilities specific to inline values.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class InlineValueWorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InlineValueWorkspaceClientCapabilities.canParse,
@@ -22787,7 +23160,7 @@
   ///
   /// Note that this event is global and will force the client to refresh all
   /// inline values currently shown. It should be used with absolute care and is
-  /// useful for situation where a server for example detect a project wide
+  /// useful for situation where a server for example detects a project wide
   /// change that requires such a calculation.
   final bool? refreshSupport;
 
@@ -22837,7 +23210,8 @@
 }
 
 /// A special text edit to provide an insert and a replace operation.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class InsertReplaceEdit implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     InsertReplaceEdit.canParse,
@@ -22990,8 +23364,11 @@
   ///
   /// A snippet can define tab stops and placeholders with `$1`, `$2` and
   /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the
-  /// snippet. Placeholders with equal identifiers are linked, that is typing in
-  /// one will update others too.
+  /// snippet. Placeholders with equal identifiers are linked,
+  /// that is typing in one will update others too.
+  ///
+  /// See also:
+  /// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
   static const Snippet = InsertTextFormat._(2);
 
   @override
@@ -23009,7 +23386,8 @@
 }
 
 /// How whitespace and indentation is handled during completion item insertion.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class InsertTextMode implements ToJsonable {
   const InsertTextMode(this._value);
   const InsertTextMode.fromJson(this._value);
@@ -23048,6 +23426,9 @@
       other is InsertTextMode && other._value == _value;
 }
 
+/// Client capabilities for the linked editing range request.
+///
+/// @since 3.16.0
 class LinkedEditingRangeClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     LinkedEditingRangeClientCapabilities.canParse,
@@ -23456,6 +23837,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The result of a linked editing range request.
+///
+/// @since 3.16.0
 class LinkedEditingRanges implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     LinkedEditingRanges.canParse,
@@ -23479,7 +23863,7 @@
     );
   }
 
-  /// A list of ranges that can be renamed together. The ranges must have
+  /// A list of ranges that can be edited together. The ranges must have
   /// identical length and contain identical text content. The ranges cannot
   /// overlap.
   final List<Range> ranges;
@@ -23558,6 +23942,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents a location inside a resource, such as a line inside a text file.
 class Location implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Location.canParse,
@@ -23653,6 +24038,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Represents the connection of two locations. Provides additional metadata
+/// over normal locations,
+/// including an origin range.
 class LocationLink implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     LocationLink.canParse,
@@ -23688,7 +24076,7 @@
   /// Span of the origin of this link.
   ///
   /// Used as the underlined span for mouse interaction. Defaults to the word
-  /// range at the mouse position.
+  /// range at the definition position.
   final Range? originSelectionRange;
 
   /// The full target range of this link. If the target for example is a symbol
@@ -23698,7 +24086,7 @@
   final Range targetRange;
 
   /// The range that should be selected and revealed when this link is being
-  /// followed, e.g the name of a function. Must be contained by the the
+  /// followed, e.g the name of a function. Must be contained by the
   /// `targetRange`. See also `DocumentSymbol#range`
   final Range targetSelectionRange;
 
@@ -23815,6 +24203,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The log message parameters.
 class LogMessageParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     LogMessageParams.canParse,
@@ -23836,10 +24225,10 @@
     );
   }
 
-  /// The actual message
+  /// The actual message.
   final String message;
 
-  /// The message type.
+  /// The message type. See {@link MessageType}
   final MessageType type;
 
   @override
@@ -23934,11 +24323,7 @@
     );
   }
 
-  /// The message to be logged.
   final String message;
-
-  /// Additional information that can be computed if the `trace` configuration
-  /// is set to `'verbose'`
   final String? verbose;
 
   @override
@@ -24007,7 +24392,8 @@
 }
 
 /// Client capabilities specific to the used markdown parser.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class MarkdownClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     MarkdownClientCapabilities.canParse,
@@ -24036,7 +24422,8 @@
   }
 
   /// A list of HTML tags that the client allows / supports in Markdown.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final List<String>? allowedTags;
 
   /// The name of the parser.
@@ -24136,18 +24523,22 @@
 /// `plaintext` and `markdown` as markup kinds.
 ///
 /// If the kind is `markdown` then the value can contain fenced code blocks like
-/// in GitHub issues.
+/// in GitHub issues. See
+/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
 ///
 /// Here is an example how such a string can be constructed using JavaScript /
-/// TypeScript: ```typescript let markdown: MarkdownContent = {
-/// 	kind: MarkupKind.Markdown,
-/// 	value: [
-/// 		'# Header',
-/// 		'Some text',
-/// 		'```typescript',
-/// 		'someCode();',
-/// 		'```'
-/// 	].join('\n') }; ```
+/// TypeScript:
+/// ```ts let markdown: MarkdownContent = {
+///  kind: MarkupKind.Markdown,
+///  value: [
+///    '# Header',
+///    'Some text',
+///    '```typescript',
+///    'someCode();',
+///    '```'
+///  ].join('\n')
+/// };
+/// ```
 ///
 /// *Please Note* that clients might sanitize the return markdown. A client
 /// could decide to remove HTML from the markdown to avoid script execution.
@@ -24358,6 +24749,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The message type
 class MessageType implements ToJsonable {
   const MessageType(this._value);
   const MessageType.fromJson(this._value);
@@ -24394,7 +24786,7 @@
       other is MessageType && other._value == _value;
 }
 
-/// Valid LSP methods known at the time of code generation from the spec.
+/// All standard LSP Methods read from the JSON spec.
 class Method implements ToJsonable {
   const Method(this._value);
   const Method.fromJson(this._value);
@@ -24723,6 +25115,8 @@
 }
 
 /// Moniker definition to match LSIF 0.5 moniker definition.
+///
+/// @since 3.16.0
 class Moniker implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Moniker.canParse,
@@ -24875,6 +25269,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client capabilities specific to the moniker request.
+///
+/// @since 3.16.0
 class MonikerClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     MonikerClientCapabilities.canParse,
@@ -24892,10 +25289,9 @@
     );
   }
 
-  /// Whether implementation supports dynamic registration. If this is set to
-  /// `true` the client supports the new `(TextDocumentRegistrationOptions &
-  /// StaticRegistrationOptions)` return value for the corresponding server
-  /// capability as well.
+  /// Whether moniker supports dynamic registration. If this is set to `true`
+  /// the client supports the new `MonikerRegistrationOptions` return value for
+  /// the corresponding server capability as well.
   final bool? dynamicRegistration;
 
   @override
@@ -24943,6 +25339,8 @@
 }
 
 /// The moniker kind.
+///
+/// @since 3.16.0
 class MonikerKind implements ToJsonable {
   const MonikerKind(this._value);
   const MonikerKind.fromJson(this._value);
@@ -25324,7 +25722,8 @@
 /// A cell's document URI must be unique across ALL notebook cells and can
 /// therefore be used to uniquely identify a notebook cell or the cell's text
 /// document.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookCell implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookCell.canParse,
@@ -25367,6 +25766,8 @@
   final NotebookCellKind kind;
 
   /// Additional metadata stored with the cell.
+  ///
+  /// Note: should always be an object literal (e.g. LSPObject)
   final Object? metadata;
 
   @override
@@ -25464,7 +25865,8 @@
 }
 
 /// A change describing how to move a `NotebookCell` array from state S to S'.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookCellArrayChange implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookCellArrayChange.canParse,
@@ -25594,7 +25996,8 @@
 }
 
 /// A notebook cell kind.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookCellKind implements ToJsonable {
   const NotebookCellKind(this._value);
   const NotebookCellKind.fromJson(this._value);
@@ -25627,7 +26030,8 @@
 
 /// A notebook cell text document filter denotes a cell text document by
 /// different properties.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookCellTextDocumentFilter implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookCellTextDocumentFilter.canParse,
@@ -25748,7 +26152,8 @@
 }
 
 /// A notebook document.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocument implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocument.canParse,
@@ -25788,6 +26193,8 @@
   final List<NotebookCell> cells;
 
   /// Additional metadata stored with the notebook document.
+  ///
+  /// Note: should always be an object literal (e.g. LSPObject)
   final Object? metadata;
 
   /// The type of the notebook.
@@ -25923,7 +26330,8 @@
 }
 
 /// A change event for a notebook document.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentChangeEvent implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocumentChangeEvent.canParse,
@@ -25952,6 +26360,8 @@
   final NotebookDocumentChangeEventCells? cells;
 
   /// The changed meta data if any.
+  ///
+  /// Note: should always be an object literal (e.g. LSPObject)
   final Object? metadata;
 
   @override
@@ -26405,7 +26815,8 @@
 }
 
 /// Capabilities specific to the notebook document support.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocumentClientCapabilities.canParse,
@@ -26426,7 +26837,8 @@
   }
 
   /// Capabilities specific to notebook document synchronization
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final NotebookDocumentSyncClientCapabilities synchronization;
 
   @override
@@ -26507,13 +26919,13 @@
     );
   }
 
-  /// The type of the enclosing notebook.
+  /// The type of the enclosing notebook. */
   final String notebookType;
 
-  /// A glob pattern.
+  /// A glob pattern. */
   final String? pattern;
 
-  /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+  /// A Uri scheme, like `file` or `untitled`. */
   final String? scheme;
 
   @override
@@ -26624,13 +27036,13 @@
     );
   }
 
-  /// The type of the enclosing notebook.
+  /// The type of the enclosing notebook. */
   final String? notebookType;
 
-  /// A glob pattern.
+  /// A glob pattern. */
   final String? pattern;
 
-  /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+  /// A Uri scheme, like `file` or `untitled`.*/
   final String scheme;
 
   @override
@@ -26741,13 +27153,13 @@
     );
   }
 
-  /// The type of the enclosing notebook.
+  /// The type of the enclosing notebook. */
   final String? notebookType;
 
-  /// A glob pattern.
+  /// A glob pattern. */
   final String pattern;
 
-  /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+  /// A Uri scheme, like `file` or `untitled`. */
   final String? scheme;
 
   @override
@@ -26834,7 +27246,8 @@
 }
 
 /// A literal to identify a notebook document in the client.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentIdentifier implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocumentIdentifier.canParse,
@@ -26906,7 +27319,8 @@
 }
 
 /// Notebook specific client capabilities.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentSyncClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocumentSyncClientCapabilities.canParse,
@@ -27004,13 +27418,14 @@
 
 /// Options specific to a notebook plus its cells to be synced to the server.
 ///
-/// If a selector provider a notebook document filter but no cell selector all
+/// If a selector provides a notebook document filter but no cell selector all
 /// cells of a matching notebook document will be synced.
 ///
 /// If a selector provides no notebook document filter but only a cell selector
 /// all notebook document that contain at least one matching cell will be
 /// synced.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentSyncOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     NotebookDocumentSyncOptions.canParse,
@@ -27551,7 +27966,8 @@
 }
 
 /// Registration options specific to a notebook.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class NotebookDocumentSyncRegistrationOptions
     implements
         NotebookDocumentSyncOptions,
@@ -27708,6 +28124,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A text document identifier to optionally denote a specific version of a text
+/// document.
 class OptionalVersionedTextDocumentIdentifier
     implements TextDocumentIdentifier, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -27731,19 +28149,16 @@
     );
   }
 
-  /// The text document's URI.
+  /// The text document's uri.
   @override
   final String uri;
 
-  /// The version number of this document. If an optional versioned text
-  /// document identifier is sent from the server to the client and the file is
-  /// not open in the editor (the server has not received an open notification
-  /// before) the server can send `null` to indicate that the version is known
-  /// and the content on disk is the master (as specified with document content
+  /// 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
+  /// in the editor (the server has not received an open notification before)
+  /// the server can send `null` to indicate that the version is unknown and the
+  /// content on disk is the truth (as specified with document content
   /// ownership).
-  ///
-  /// The version number of a document will increase after each change,
-  /// including undo/redo. The number doesn't need to be consecutive.
   final int? version;
 
   @override
@@ -28179,6 +28594,32 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Position in a text document expressed as zero-based line and character
+/// offset. Prior to 3.17 the offsets were always based on a UTF-16 string
+/// representation. So a string of the form `a𐐀b` the character offset of the
+/// character `a` is 0, the character offset of `𐐀` is 1 and the character
+/// offset of b is 3 since `𐐀` is represented using two code units in UTF-16.
+/// Since 3.17 clients and servers can agree on a different string encoding
+/// representation (e.g. UTF-8). The client announces it's supported encoding
+/// via the client capability `general.positionEncodings`. The value is an array
+/// of position encodings the client supports, with decreasing preference (e.g.
+/// the encoding at index `0` is the most preferred one). To stay backwards
+/// compatible the only mandatory encoding is UTF-16 represented via the string
+/// `utf-16`. The server can pick one of the encodings offered by the client and
+/// signals that encoding back to the client via the initialize result's
+/// property `capabilities.positionEncoding`. If the string value `utf-16` is
+/// missing from the client's capability `general.positionEncodings` servers can
+/// safely assume that the client supports UTF-16. If the server omits the
+/// position encoding in its initialize result the encoding defaults to the
+/// string value `utf-16`. Implementation considerations: since the conversion
+/// from one encoding into another requires the content of the file / line the
+/// conversion is best done where the file is read which is usually on the
+/// server side.
+///
+/// Positions are line end character agnostic. So you can not specify a position
+/// that denotes `\r|\n` or `\n|` where `|` represents the character offset.
+///
+/// @since 3.17.0 - support for negotiated position encoding.
 class Position implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Position.canParse,
@@ -28200,14 +28641,20 @@
     );
   }
 
-  /// Character offset on a line in a document (zero-based). The meaning of this
-  /// offset is determined by the negotiated `PositionEncodingKind`.
+  /// Character offset on a line in a document (zero-based).
+  ///
+  /// The meaning of this offset is determined by the negotiated
+  /// `PositionEncodingKind`.
   ///
   /// If the character value is greater than the line length it defaults back to
   /// the line length.
   final int character;
 
   /// Line position in a document (zero-based).
+  ///
+  /// If a line number is greater than the number of lines in a document, it
+  /// defaults back to the number of lines in the document. If a line number is
+  /// negative, it defaults to 0.
   final int line;
 
   @override
@@ -28282,7 +28729,8 @@
 }
 
 /// A set of predefined position encoding kinds.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class PositionEncodingKind implements ToJsonable {
   const PositionEncodingKind(this._value);
   const PositionEncodingKind.fromJson(this._value);
@@ -28300,8 +28748,8 @@
 
   /// Character offsets count UTF-32 code units.
   ///
-  /// Implementation note: these are the same as Unicode code points, so this
-  /// `PositionEncodingKind` may also be used for an encoding-agnostic
+  /// Implementation note: these are the same as Unicode code points,
+  /// so this `PositionEncodingKind` may also be used for an encoding-agnostic
   /// representation of character offsets.
   static const UTF32 = PositionEncodingKind('utf-32');
 
@@ -28458,6 +28906,75 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+class PrepareRenameResult2 implements ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    PrepareRenameResult2.canParse,
+    PrepareRenameResult2.fromJson,
+  );
+
+  PrepareRenameResult2({
+    required this.defaultBehavior,
+  });
+  static PrepareRenameResult2 fromJson(Map<String, Object?> json) {
+    final defaultBehaviorJson = json['defaultBehavior'];
+    final defaultBehavior = defaultBehaviorJson as bool;
+    return PrepareRenameResult2(
+      defaultBehavior: defaultBehavior,
+    );
+  }
+
+  final bool defaultBehavior;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    result['defaultBehavior'] = defaultBehavior;
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      reporter.push('defaultBehavior');
+      try {
+        if (!obj.containsKey('defaultBehavior')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final defaultBehavior = obj['defaultBehavior'];
+        if (defaultBehavior == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (defaultBehavior is! bool) {
+          reporter.reportError('must be of type bool');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type PrepareRenameResult2');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is PrepareRenameResult2 &&
+        other.runtimeType == PrepareRenameResult2) {
+      return defaultBehavior == other.defaultBehavior && true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => defaultBehavior.hashCode;
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
 class PrepareSupportDefaultBehavior implements ToJsonable {
   const PrepareSupportDefaultBehavior(this._value);
   const PrepareSupportDefaultBehavior.fromJson(this._value);
@@ -28468,7 +28985,7 @@
     return obj is int;
   }
 
-  /// The client's default behavior is to select the identifier according to the
+  /// The client's default behavior is to select the identifier according the to
   /// language's syntax rule.
   static const Identifier = PrepareSupportDefaultBehavior(1);
 
@@ -28487,7 +29004,8 @@
 }
 
 /// A previous result id in a workspace pull request.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class PreviousResultId implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     PreviousResultId.canParse,
@@ -28586,7 +29104,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-class ProgressParams<T> implements ToJsonable {
+class ProgressParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ProgressParams.canParse,
     ProgressParams.fromJson,
@@ -28596,7 +29114,7 @@
     required this.token,
     this.value,
   });
-  static ProgressParams<T> fromJson<T>(Map<String, Object?> json) {
+  static ProgressParams fromJson(Map<String, Object?> json) {
     final tokenJson = json['token'];
     final token = tokenJson is int
         ? Either2<int, String>.t1(tokenJson)
@@ -28605,7 +29123,7 @@
             : (throw '''$tokenJson was not one of (int, String)'''));
     final valueJson = json['value'];
     final value = valueJson;
-    return ProgressParams<T>(
+    return ProgressParams(
       token: token,
       value: value,
     );
@@ -28647,7 +29165,7 @@
       }
       return true;
     } else {
-      reporter.reportError('must be of type ProgressParams<T>');
+      reporter.reportError('must be of type ProgressParams');
       return false;
     }
   }
@@ -28670,6 +29188,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The publish diagnostic client capabilities.
 class PublishDiagnosticsClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     PublishDiagnosticsClientCapabilities.canParse,
@@ -28708,13 +29227,15 @@
   }
 
   /// Client supports a codeDescription property
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? codeDescriptionSupport;
 
   /// Whether code action supports the `data` property which is preserved
   /// between a `textDocument/publishDiagnostics` and `textDocument/codeAction`
   /// request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? dataSupport;
 
   /// Whether the clients accepts diagnostics with related information.
@@ -28722,12 +29243,14 @@
 
   /// Client supports the tag property to provide meta data about a diagnostic.
   /// Clients supporting tags have to handle unknown tags gracefully.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final PublishDiagnosticsClientCapabilitiesTagSupport? tagSupport;
 
   /// Whether the client interprets the version property of the
   /// `textDocument/publishDiagnostics` notification's parameter.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? versionSupport;
 
   @override
@@ -28918,6 +29441,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The publish diagnostic notification's parameters.
 class PublishDiagnosticsParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     PublishDiagnosticsParams.canParse,
@@ -28953,7 +29477,8 @@
 
   /// Optional the version number of the document the diagnostics are published
   /// for.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final int? version;
 
   @override
@@ -29047,6 +29572,18 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A range in a text document expressed as (zero-based) start and end
+/// positions.
+///
+/// If you want to specify a range that contains a line including the line
+/// ending character(s) then use an end position denoting the start of the next
+/// line. For example:
+/// ```ts
+/// {
+///     start: { line: 5, character: 23 }
+///     end : { line 6, character : 0 }
+/// }
+/// ```
 class Range implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Range.canParse,
@@ -29145,6 +29682,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client Capabilities for a ReferencesRequest.
 class ReferenceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ReferenceClientCapabilities.canParse,
@@ -29209,6 +29747,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Value-object that contains additional information when requesting
+/// references.
 class ReferenceContext implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ReferenceContext.canParse,
@@ -29278,6 +29818,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Reference options.
 class ReferenceOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ReferenceOptions.canParse,
@@ -29344,6 +29885,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a ReferencesRequest.
 class ReferenceParams
     implements
         PartialResultParams,
@@ -29543,6 +30085,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a ReferencesRequest.
 class ReferenceRegistrationOptions
     implements ReferenceOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -29648,7 +30191,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// General parameters to register for a capability.
+/// General parameters to to register for an notification or to register a
+/// provider.
 class Registration implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Registration.canParse,
@@ -29839,6 +30383,8 @@
 }
 
 /// Client capabilities specific to regular expressions.
+///
+/// @since 3.16.0
 class RegularExpressionsClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RegularExpressionsClientCapabilities.canParse,
@@ -29935,7 +30481,8 @@
 }
 
 /// A full diagnostic report with a set of related documents.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class RelatedFullDocumentDiagnosticReport
     implements FullDocumentDiagnosticReport, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -29998,7 +30545,8 @@
   /// file B which A depends on. An example of such a language is C/C++ where
   /// marco definitions in a file a.cpp and result in errors in a header file
   /// b.hpp.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Map<
       String,
       Either2<FullDocumentDiagnosticReport,
@@ -30135,7 +30683,8 @@
 }
 
 /// An unchanged diagnostic report with a set of related documents.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class RelatedUnchangedDocumentDiagnosticReport
     implements UnchangedDocumentDiagnosticReport, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -30189,7 +30738,8 @@
   /// file B which A depends on. An example of such a language is C/C++ where
   /// marco definitions in a file a.cpp and result in errors in a header file
   /// b.hpp.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Map<
       String,
       Either2<FullDocumentDiagnosticReport,
@@ -30311,7 +30861,8 @@
 /// A relative pattern is a helper to construct glob patterns that are matched
 /// relatively to a base URI. The common value for a `baseUri` is a workspace
 /// folder root, but it can be another absolute URI as well.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class RelativePattern implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RelativePattern.canParse,
@@ -30455,23 +31006,25 @@
   /// Whether rename supports dynamic registration.
   final bool? dynamicRegistration;
 
-  /// Whether th client honors the change annotations in text edits and resource
-  /// operations returned via the rename request's workspace edit by for example
-  /// presenting the workspace edit in the user interface and asking for
-  /// confirmation.
-  ///  @since 3.16.0
+  /// Whether the client honors the change annotations in text edits and
+  /// resource operations returned via the rename request's workspace edit by
+  /// for example presenting the workspace edit in the user interface and asking
+  /// for confirmation.
+  ///
+  /// @since 3.16.0
   final bool? honorsChangeAnnotations;
 
   /// Client supports testing for validity of rename operations before
   /// execution.
-  ///  @since version 3.12.0
+  ///
+  /// @since 3.12.0
   final bool? prepareSupport;
 
-  /// Client supports the default behavior result (`{ defaultBehavior: boolean
-  /// }`).
+  /// Client supports the default behavior result.
   ///
   /// The value indicates the default behavior used by the client.
-  ///  @since version 3.16.0
+  ///
+  /// @since 3.16.0
   final PrepareSupportDefaultBehavior? prepareSupportDefaultBehavior;
 
   @override
@@ -30573,7 +31126,7 @@
 }
 
 /// Rename file operation
-class RenameFile implements ToJsonable {
+class RenameFile implements ResourceOperation, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RenameFile.canParse,
     RenameFile.fromJson,
@@ -30613,10 +31166,13 @@
   }
 
   /// An optional annotation identifier describing the operation.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
+  @override
   final String? annotationId;
 
   /// A rename
+  @override
   final String kind;
 
   /// The new location.
@@ -30843,7 +31399,8 @@
 
 /// The parameters sent in notifications/requests for user-initiated renames of
 /// files.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class RenameFilesParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RenameFilesParams.canParse,
@@ -30919,6 +31476,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Provider options for a RenameRequest.
 class RenameOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RenameOptions.canParse,
@@ -30944,6 +31502,8 @@
   }
 
   /// Renames should be checked and tested before being executed.
+  ///
+  /// @since version 3.12.0
   final bool? prepareProvider;
   @override
   final bool? workDoneProgress;
@@ -31009,8 +31569,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-class RenameParams
-    implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable {
+/// The parameters of a RenameRequest.
+class RenameParams implements WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     RenameParams.canParse,
     RenameParams.fromJson,
@@ -31047,15 +31607,13 @@
   }
 
   /// The new name of the symbol. If the given name is not valid the request
-  /// must return a [ResponseError] with an appropriate message set.
+  /// must return a ResponseError with an appropriate message set.
   final String newName;
 
-  /// The position inside the text document.
-  @override
+  /// The position at which this request was sent.
   final Position position;
 
-  /// The text document.
-  @override
+  /// The document to rename.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
@@ -31173,6 +31731,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a RenameRequest.
 class RenameRegistrationOptions
     implements RenameOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -31208,6 +31767,8 @@
   final List<TextDocumentFilterWithScheme>? documentSelector;
 
   /// Renames should be checked and tested before being executed.
+  ///
+  /// @since version 3.12.0
   @override
   final bool? prepareProvider;
   @override
@@ -31301,6 +31862,110 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A generic resource operation.
+class ResourceOperation implements ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    ResourceOperation.canParse,
+    ResourceOperation.fromJson,
+  );
+
+  ResourceOperation({
+    this.annotationId,
+    required this.kind,
+  });
+  static ResourceOperation fromJson(Map<String, Object?> json) {
+    if (RenameFile.canParse(json, nullLspJsonReporter)) {
+      return RenameFile.fromJson(json);
+    }
+    if (CreateFile.canParse(json, nullLspJsonReporter)) {
+      return CreateFile.fromJson(json);
+    }
+    if (DeleteFile.canParse(json, nullLspJsonReporter)) {
+      return DeleteFile.fromJson(json);
+    }
+    final annotationIdJson = json['annotationId'];
+    final annotationId = annotationIdJson as String?;
+    final kindJson = json['kind'];
+    final kind = kindJson as String;
+    return ResourceOperation(
+      annotationId: annotationId,
+      kind: kind,
+    );
+  }
+
+  /// An optional annotation identifier describing the operation.
+  ///
+  /// @since 3.16.0
+  final String? annotationId;
+
+  /// The resource operation kind.
+  final String kind;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    if (annotationId != null) {
+      result['annotationId'] = annotationId;
+    }
+    result['kind'] = kind;
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      reporter.push('annotationId');
+      try {
+        final annotationId = obj['annotationId'];
+        if (annotationId != null && annotationId is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('kind');
+      try {
+        if (!obj.containsKey('kind')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final kind = obj['kind'];
+        if (kind == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (kind is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type ResourceOperation');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is ResourceOperation && other.runtimeType == ResourceOperation) {
+      return annotationId == other.annotationId && kind == other.kind && true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        annotationId,
+        kind,
+      );
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
 class ResourceOperationKind implements ToJsonable {
   const ResourceOperationKind._(this._value);
   const ResourceOperationKind.fromJson(this._value);
@@ -31340,6 +32005,7 @@
       other is ResourceOperationKind && other._value == _value;
 }
 
+/// Save options.
 class SaveOptions implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SaveOptions.canParse,
@@ -31350,6 +32016,10 @@
     this.includeText,
   });
   static SaveOptions fromJson(Map<String, Object?> json) {
+    if (TextDocumentSaveRegistrationOptions.canParse(
+        json, nullLspJsonReporter)) {
+      return TextDocumentSaveRegistrationOptions.fromJson(json);
+    }
     final includeTextJson = json['includeText'];
     final includeText = includeTextJson as bool?;
     return SaveOptions(
@@ -31403,6 +32073,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A selection range represents a part of a selection hierarchy. A selection
+/// range may have a parent selection range that contains it.
 class SelectionRange implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SelectionRange.canParse,
@@ -31430,7 +32102,7 @@
   /// must contain `this.range`.
   final SelectionRange? parent;
 
-  /// The range ([Range]) of this selection range.
+  /// The range of this selection range.
   final Range range;
 
   @override
@@ -31632,6 +32304,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A parameter literal used in selection range requests.
 class SelectionRangeParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -31935,6 +32608,10 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A set of predefined token modifiers. This set is not fixed an clients can
+/// specify additional token types via the corresponding client capabilities.
+///
+/// @since 3.16.0
 class SemanticTokenModifiers implements ToJsonable {
   const SemanticTokenModifiers(this._value);
   const SemanticTokenModifiers.fromJson(this._value);
@@ -31970,6 +32647,10 @@
       other is SemanticTokenModifiers && other._value == _value;
 }
 
+/// A set of predefined token types. This set is not fixed an clients can
+/// specify additional token types via the corresponding client capabilities.
+///
+/// @since 3.16.0
 class SemanticTokenTypes implements ToJsonable {
   const SemanticTokenTypes(this._value);
   const SemanticTokenTypes.fromJson(this._value);
@@ -32023,6 +32704,7 @@
       other is SemanticTokenTypes && other._value == _value;
 }
 
+/// @since 3.16.0
 class SemanticTokens implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokens.canParse,
@@ -32121,6 +32803,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensClientCapabilities.canParse,
@@ -32183,7 +32866,8 @@
   /// returned semantic tokens for colorization.
   ///
   /// If the value is `undefined` then the client behavior is not specified.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final bool? augmentsSyntaxTokens;
 
   /// Whether implementation supports dynamic registration. If this is set to
@@ -32192,7 +32876,7 @@
   /// capability as well.
   final bool? dynamicRegistration;
 
-  /// The formats the clients supports.
+  /// The token formats the clients supports.
   final List<TokenFormat> formats;
 
   /// Whether the client supports tokens that can span multiple lines.
@@ -32212,9 +32896,10 @@
   final SemanticTokensClientCapabilitiesRequests requests;
 
   /// Whether the client allows the server to actively cancel a semantic token
-  /// request, e.g. supports returning ErrorCodes.ServerCancelled. If a server
-  /// does the client needs to retrigger the request.
-  ///  @since 3.17.0
+  /// request, e.g. supports returning LSPErrorCodes.ServerCancelled. If a
+  /// server does the client needs to retrigger the request.
+  ///
+  /// @since 3.17.0
   final bool? serverCancelSupport;
 
   /// The token modifiers that the client supports.
@@ -32651,6 +33336,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensDelta implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensDelta.canParse,
@@ -32749,6 +33435,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensDeltaParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -32916,6 +33603,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensDeltaPartialResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensDeltaPartialResult.canParse,
@@ -32991,6 +33679,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensEdit implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensEdit.canParse,
@@ -33116,6 +33805,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensLegend implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensLegend.canParse,
@@ -33225,6 +33915,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensOptions.canParse,
@@ -33493,6 +34184,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -33631,6 +34323,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensPartialResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensPartialResult.canParse,
@@ -33701,6 +34394,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensRangeParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -33867,6 +34561,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensRegistrationOptions
     implements
         SemanticTokensOptions,
@@ -34100,6 +34795,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.16.0
 class SemanticTokensWorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SemanticTokensWorkspaceClientCapabilities.canParse,
@@ -34123,7 +34819,7 @@
   ///
   /// Note that this event is global and will force the client to refresh all
   /// semantic tokens currently shown. It should be used with absolute care and
-  /// is useful for situation where a server for example detect a project wide
+  /// is useful for situation where a server for example detects a project wide
   /// change that requires such a calculation.
   final bool? refreshSupport;
 
@@ -34172,6 +34868,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Defines the capabilities provided by a language server.
 class ServerCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ServerCapabilities.canParse,
@@ -34669,28 +35366,27 @@
   }
 
   /// The server provides call hierarchy support.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Either3<bool, CallHierarchyOptions, CallHierarchyRegistrationOptions>?
       callHierarchyProvider;
 
-  /// The server provides code actions. The `CodeActionOptions` return type is
-  /// only valid if the client signals code action literal support via the
-  /// property `textDocument.codeAction.codeActionLiteralSupport`.
+  /// The server provides code actions. CodeActionOptions may only be specified
+  /// if the client states that it supports `codeActionLiteralSupport` in its
+  /// initial `initialize` request.
   final Either2<bool, CodeActionOptions>? codeActionProvider;
 
   /// The server provides code lens.
   final CodeLensOptions? codeLensProvider;
 
   /// The server provides color provider support.
-  ///  @since 3.6.0
   final Either3<bool, DocumentColorOptions, DocumentColorRegistrationOptions>?
       colorProvider;
 
   /// The server provides completion support.
   final CompletionOptions? completionProvider;
 
-  /// The server provides go to declaration support.
-  ///  @since 3.14.0
+  /// The server provides Goto Declaration support.
   final Either3<bool, DeclarationOptions, DeclarationRegistrationOptions>?
       declarationProvider;
 
@@ -34698,7 +35394,8 @@
   final Either2<bool, DefinitionOptions>? definitionProvider;
 
   /// The server has support for pull model diagnostics.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Either2<DiagnosticOptions, DiagnosticRegistrationOptions>?
       diagnosticProvider;
 
@@ -34728,40 +35425,43 @@
   final Object? experimental;
 
   /// The server provides folding provider support.
-  ///  @since 3.10.0
   final Either3<bool, FoldingRangeOptions, FoldingRangeRegistrationOptions>?
       foldingRangeProvider;
 
   /// The server provides hover support.
   final Either2<bool, HoverOptions>? hoverProvider;
 
-  /// The server provides goto implementation support.
-  ///  @since 3.6.0
+  /// The server provides Goto Implementation support.
   final Either3<bool, ImplementationOptions, ImplementationRegistrationOptions>?
       implementationProvider;
 
   /// The server provides inlay hints.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Either3<bool, InlayHintOptions, InlayHintRegistrationOptions>?
       inlayHintProvider;
 
   /// The server provides inline values.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Either3<bool, InlineValueOptions, InlineValueRegistrationOptions>?
       inlineValueProvider;
 
   /// The server provides linked editing range support.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Either3<bool, LinkedEditingRangeOptions,
       LinkedEditingRangeRegistrationOptions>? linkedEditingRangeProvider;
 
-  /// Whether server provides moniker support.
-  ///  @since 3.16.0
+  /// The server provides moniker support.
+  ///
+  /// @since 3.16.0
   final Either3<bool, MonikerOptions, MonikerRegistrationOptions>?
       monikerProvider;
 
   /// Defines how notebook documents are synced.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Either2<NotebookDocumentSyncOptions,
       NotebookDocumentSyncRegistrationOptions>? notebookDocumentSync;
 
@@ -34772,7 +35472,8 @@
   /// that a server can return is 'utf-16'.
   ///
   /// If omitted it defaults to 'utf-16'.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final PositionEncodingKind? positionEncoding;
 
   /// The server provides find references support.
@@ -34784,12 +35485,12 @@
   final Either2<bool, RenameOptions>? renameProvider;
 
   /// The server provides selection range support.
-  ///  @since 3.15.0
   final Either3<bool, SelectionRangeOptions, SelectionRangeRegistrationOptions>?
       selectionRangeProvider;
 
   /// The server provides semantic tokens support.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Either2<SemanticTokensOptions, SemanticTokensRegistrationOptions>?
       semanticTokensProvider;
 
@@ -34798,22 +35499,21 @@
 
   /// Defines how text documents are synced. Is either a detailed structure
   /// defining each notification or for backwards compatibility the
-  /// TextDocumentSyncKind number. If omitted it defaults to
-  /// `TextDocumentSyncKind.None`.
+  /// TextDocumentSyncKind number.
   final Either2<TextDocumentSyncKind, TextDocumentSyncOptions>?
       textDocumentSync;
 
-  /// The server provides goto type definition support.
-  ///  @since 3.6.0
+  /// The server provides Goto Type Definition support.
   final Either3<bool, TypeDefinitionOptions, TypeDefinitionRegistrationOptions>?
       typeDefinitionProvider;
 
   /// The server provides type hierarchy support.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final Either3<bool, TypeHierarchyOptions, TypeHierarchyRegistrationOptions>?
       typeHierarchyProvider;
 
-  /// Workspace specific server capabilities
+  /// Workspace specific server capabilities.
   final ServerCapabilitiesWorkspace? workspace;
 
   /// The server provides workspace symbol support.
@@ -35517,12 +36217,15 @@
     );
   }
 
-  /// The server is interested in file notifications/requests.
-  ///  @since 3.16.0
+  /// The server is interested in notifications/requests for operations on
+  /// files.
+  ///
+  /// @since 3.16.0
   final FileOperationOptions? fileOperations;
 
   /// The server supports workspace folder.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final WorkspaceFoldersServerCapabilities? workspaceFolders;
 
   @override
@@ -35602,21 +36305,18 @@
   });
   static SetTraceParams fromJson(Map<String, Object?> json) {
     final valueJson = json['value'];
-    final value = const {'off', 'messages', 'verbose'}.contains(valueJson)
-        ? valueJson as String
-        : throw '''$valueJson was not one of ('off', 'messages', 'verbose')''';
+    final value = TraceValues.fromJson(valueJson as String);
     return SetTraceParams(
       value: value,
     );
   }
 
-  /// The new value that should be assigned to the trace setting.
-  final String value;
+  final TraceValues value;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['value'] = value;
+    result['value'] = value.toJson();
     return result;
   }
 
@@ -35633,9 +36333,8 @@
           reporter.reportError('must not be null');
           return false;
         }
-        if (value != 'off' && value != 'messages' && value != 'verbose') {
-          reporter.reportError(
-              'must be one of the literals \'off\', \'messages\', \'verbose\'');
+        if (!TraceValues.canParse(value, reporter)) {
+          reporter.reportError('must be of type TraceValues');
           return false;
         }
       } finally {
@@ -35663,8 +36362,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Client capabilities for the show document request.
-///  @since 3.16.0
+/// Client capabilities for the showDocument request.
+///
+/// @since 3.16.0
 class ShowDocumentClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ShowDocumentClientCapabilities.canParse,
@@ -35682,7 +36382,7 @@
     );
   }
 
-  /// The client has support for the show document request.
+  /// The client has support for the showDocument request.
   final bool support;
 
   @override
@@ -35736,7 +36436,8 @@
 }
 
 /// Params to show a document.
-///  @since 3.16.0
+///
+/// @since 3.16.0
 class ShowDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ShowDocumentParams.canParse,
@@ -35884,8 +36585,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// The result of an show document request.
-///  @since 3.16.0
+/// The result of a showDocument request.
+///
+/// @since 3.16.0
 class ShowDocumentResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ShowDocumentResult.canParse,
@@ -35956,6 +36658,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameters of a notification message.
 class ShowMessageParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     ShowMessageParams.canParse,
@@ -35980,7 +36683,7 @@
   /// The actual message.
   final String message;
 
-  /// The message type.
+  /// The message type. See {@link MessageType}
   final MessageType type;
 
   @override
@@ -36149,7 +36852,7 @@
   }
 
   /// Whether the client supports additional attributes which are preserved and
-  /// sent back to the server in the request's response.
+  /// send back to the server in the request's response.
   final bool? additionalPropertiesSupport;
 
   @override
@@ -36231,10 +36934,10 @@
   /// The message action items to present.
   final List<MessageActionItem>? actions;
 
-  /// The actual message
+  /// The actual message.
   final String message;
 
-  /// The message type.
+  /// The message type. See {@link MessageType}
   final MessageType type;
 
   @override
@@ -36369,8 +37072,8 @@
   final int? activeParameter;
 
   /// The active signature. If omitted or the value lies outside the range of
-  /// `signatures` the value defaults to zero or is ignore if the
-  /// `SignatureHelp` as no signatures.
+  /// `signatures` the value defaults to zero or is ignored if the
+  /// `SignatureHelp` has no signatures.
   ///
   /// Whenever possible implementors should make an active decision about the
   /// active signature and shouldn't rely on a default value.
@@ -36379,8 +37082,7 @@
   /// better express this.
   final int? activeSignature;
 
-  /// One or more signatures. If no signatures are available the signature help
-  /// request should return `null`.
+  /// One or more signatures.
   final List<SignatureInformation> signatures;
 
   @override
@@ -36468,6 +37170,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client Capabilities for a SignatureHelpRequest.
 class SignatureHelpClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SignatureHelpClientCapabilities.canParse,
@@ -36500,7 +37203,8 @@
   /// `textDocument/signatureHelp` request. A client that opts into
   /// contextSupport will also support the `retriggerCharacters` on
   /// `SignatureHelpOptions`.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? contextSupport;
 
   /// Whether signature help supports dynamic registration.
@@ -36625,11 +37329,12 @@
 
   /// The client supports the `activeParameter` property on
   /// `SignatureInformation` literal.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final bool? activeParameterSupport;
 
-  /// Client supports the follow content formats for the documentation property.
-  /// The order describes the preferred format of the client.
+  /// Client supports the following content formats for the documentation
+  /// property. The order describes the preferred format of the client.
   final List<MarkupKind>? documentationFormat;
 
   /// Client capabilities specific to parameter information.
@@ -36724,7 +37429,8 @@
 
 /// Additional information about the context in which a signature help request
 /// was triggered.
-///  @since 3.15.0
+///
+/// @since 3.15.0
 class SignatureHelpContext implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SignatureHelpContext.canParse,
@@ -36766,15 +37472,15 @@
 
   /// `true` if signature help was already showing when it was triggered.
   ///
-  /// Retriggers occur when the signature help is already active and can be
+  /// Retriggers occurs when the signature help is already active and can be
   /// caused by actions such as typing a trigger character, a cursor move, or
   /// document content changes.
   final bool isRetrigger;
 
   /// Character that caused signature help to be triggered.
   ///
-  /// This is undefined when triggerKind !==
-  /// SignatureHelpTriggerKind.TriggerCharacter
+  /// This is undefined when `triggerKind !==
+  /// SignatureHelpTriggerKind.TriggerCharacter`
   final String? triggerCharacter;
 
   /// Action that caused signature help to be triggered.
@@ -36885,6 +37591,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Server Capabilities for a SignatureHelpRequest.
 class SignatureHelpOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SignatureHelpOptions.canParse,
@@ -36921,10 +37628,11 @@
   ///
   /// These trigger characters are only active when signature help is already
   /// showing. All trigger characters are also counted as re-trigger characters.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final List<String>? retriggerCharacters;
 
-  /// The characters that trigger signature help automatically.
+  /// List of characters that trigger signature help automatically.
   final List<String>? triggerCharacters;
   @override
   final bool? workDoneProgress;
@@ -37012,6 +37720,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Parameters for a SignatureHelpRequest.
 class SignatureHelpParams
     implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -37054,7 +37763,8 @@
   /// The signature help context. This is only available if the client specifies
   /// to send this using the client capability
   /// `textDocument.signatureHelp.contextSupport === true`
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final SignatureHelpContext? context;
 
   /// The position inside the text document.
@@ -37176,6 +37886,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a SignatureHelpRequest.
 class SignatureHelpRegistrationOptions
     implements
         SignatureHelpOptions,
@@ -37225,11 +37936,12 @@
   ///
   /// These trigger characters are only active when signature help is already
   /// showing. All trigger characters are also counted as re-trigger characters.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   @override
   final List<String>? retriggerCharacters;
 
-  /// The characters that trigger signature help automatically.
+  /// List of characters that trigger signature help automatically.
   @override
   final List<String>? triggerCharacters;
   @override
@@ -37345,7 +38057,8 @@
 }
 
 /// How a signature help was triggered.
-///  @since 3.15.0
+///
+/// @since 3.15.0
 class SignatureHelpTriggerKind implements ToJsonable {
   const SignatureHelpTriggerKind(this._value);
   const SignatureHelpTriggerKind.fromJson(this._value);
@@ -37424,7 +38137,8 @@
   /// The index of the active parameter.
   ///
   /// If provided, this is used in place of `SignatureHelp.activeParameter`.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final int? activeParameter;
 
   /// The human-readable doc-comment of this signature. Will be shown in the UI
@@ -37562,7 +38276,8 @@
 
   /// The client supports processing label offsets instead of a simple label
   /// string.
-  ///  @since 3.14.0
+  ///
+  /// @since 3.14.0
   final bool? labelOffsetSupport;
 
   @override
@@ -37722,8 +38437,7 @@
 
 /// Represents information about programming constructs like variables, classes,
 /// interfaces etc.
-///  @deprecated use DocumentSymbol or WorkspaceSymbol instead.
-class SymbolInformation implements ToJsonable {
+class SymbolInformation implements BaseSymbolInformation, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SymbolInformation.canParse,
     SymbolInformation.fromJson,
@@ -37766,31 +38480,37 @@
   /// user interface purposes (e.g. to render a qualifier in the user interface
   /// if necessary). It can't be used to re-infer a hierarchy for the document
   /// symbols.
+  @override
   final String? containerName;
 
   /// Indicates if this symbol is deprecated.
-  ///  @deprecated Use tags instead
+  ///
+  /// @deprecated Use tags instead
   final bool? deprecated;
 
   /// The kind of this symbol.
+  @override
   final SymbolKind kind;
 
   /// The location of this symbol. The location's range is used by a tool to
   /// reveal the location in the editor. If the symbol is selected in the tool
   /// the range's start information is used to position the cursor. So the range
-  /// usually spans more then the actual symbol's name and does normally include
+  /// usually spans more than the actual symbol's name and does normally include
   /// things like visibility modifiers.
   ///
-  /// The range doesn't have to denote a node range in the sense of a abstract
+  /// The range doesn't have to denote a node range in the sense of an abstract
   /// syntax tree. It can therefore not be used to re-construct a hierarchy of
   /// the symbols.
   final Location location;
 
   /// The name of this symbol.
+  @override
   final String name;
 
   /// Tags for this symbol.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
+  @override
   final List<SymbolTag>? tags;
 
   @override
@@ -37987,7 +38707,8 @@
 }
 
 /// Symbol tags are extra annotations that tweak the rendering of a symbol.
-///  @since 3.16
+///
+/// @since 3.16
 class SymbolTag implements ToJsonable {
   const SymbolTag(this._value);
   const SymbolTag.fromJson(this._value);
@@ -38015,8 +38736,7 @@
       other is SymbolTag && other._value == _value;
 }
 
-/// Describe options to be used when registering for text document change
-/// events.
+/// Describe options to be used when registered for text document change events.
 class TextDocumentChangeRegistrationOptions
     implements TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -38048,8 +38768,7 @@
   @override
   final List<TextDocumentFilterWithScheme>? documentSelector;
 
-  /// How documents are synced to the server. See TextDocumentSyncKind.Full and
-  /// TextDocumentSyncKind.Incremental.
+  /// How documents are synced to the server.
   final TextDocumentSyncKind syncKind;
 
   @override
@@ -38355,7 +39074,8 @@
   }
 
   /// Capabilities specific to the various call hierarchy requests.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final CallHierarchyClientCapabilities? callHierarchy;
 
   /// Capabilities specific to the `textDocument/codeAction` request.
@@ -38366,21 +39086,24 @@
 
   /// Capabilities specific to the `textDocument/documentColor` and the
   /// `textDocument/colorPresentation` request.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final DocumentColorClientCapabilities? colorProvider;
 
   /// Capabilities specific to the `textDocument/completion` request.
   final CompletionClientCapabilities? completion;
 
   /// Capabilities specific to the `textDocument/declaration` request.
-  ///  @since 3.14.0
+  ///
+  /// @since 3.14.0
   final DeclarationClientCapabilities? declaration;
 
   /// Capabilities specific to the `textDocument/definition` request.
   final DefinitionClientCapabilities? definition;
 
   /// Capabilities specific to the diagnostic pull model.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final DiagnosticClientCapabilities? diagnostic;
 
   /// Capabilities specific to the `textDocument/documentHighlight` request.
@@ -38393,7 +39116,8 @@
   final DocumentSymbolClientCapabilities? documentSymbol;
 
   /// Capabilities specific to the `textDocument/foldingRange` request.
-  ///  @since 3.10.0
+  ///
+  /// @since 3.10.0
   final FoldingRangeClientCapabilities? foldingRange;
 
   /// Capabilities specific to the `textDocument/formatting` request.
@@ -38403,27 +39127,31 @@
   final HoverClientCapabilities? hover;
 
   /// Capabilities specific to the `textDocument/implementation` request.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final ImplementationClientCapabilities? implementation;
 
   /// Capabilities specific to the `textDocument/inlayHint` request.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final InlayHintClientCapabilities? inlayHint;
 
   /// Capabilities specific to the `textDocument/inlineValue` request.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final InlineValueClientCapabilities? inlineValue;
 
   /// Capabilities specific to the `textDocument/linkedEditingRange` request.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final LinkedEditingRangeClientCapabilities? linkedEditingRange;
 
-  /// Capabilities specific to the `textDocument/moniker` request.
-  ///  @since 3.16.0
+  /// Client capabilities specific to the `textDocument/moniker` request.
+  ///
+  /// @since 3.16.0
   final MonikerClientCapabilities? moniker;
 
-  /// request. Capabilities specific to the `textDocument/onTypeFormatting`
-  /// request.
+  /// Capabilities specific to the `textDocument/onTypeFormatting` request.
   final DocumentOnTypeFormattingClientCapabilities? onTypeFormatting;
 
   /// Capabilities specific to the `textDocument/publishDiagnostics`
@@ -38440,23 +39168,29 @@
   final RenameClientCapabilities? rename;
 
   /// Capabilities specific to the `textDocument/selectionRange` request.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final SelectionRangeClientCapabilities? selectionRange;
 
-  /// Capabilities specific to the various semantic token requests.
-  ///  @since 3.16.0
+  /// Capabilities specific to the various semantic token request.
+  ///
+  /// @since 3.16.0
   final SemanticTokensClientCapabilities? semanticTokens;
 
   /// Capabilities specific to the `textDocument/signatureHelp` request.
   final SignatureHelpClientCapabilities? signatureHelp;
+
+  /// Defines which synchronization capabilities the client supports.
   final TextDocumentSyncClientCapabilities? synchronization;
 
   /// Capabilities specific to the `textDocument/typeDefinition` request.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final TypeDefinitionClientCapabilities? typeDefinition;
 
   /// Capabilities specific to the various type hierarchy requests.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final TypeHierarchyClientCapabilities? typeHierarchy;
 
   @override
@@ -39034,7 +39768,8 @@
   final Range range;
 
   /// The optional length of the range that got replaced.
-  ///  @deprecated use range instead.
+  ///
+  /// @deprecated use range instead.
   final int? rangeLength;
 
   /// The new text for the provided range.
@@ -39199,6 +39934,11 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Describes textual changes on a text document. A TextDocumentEdit describes
+/// all changes on a document version Si and after they are applied move the
+/// document to version Si+1. So the creator of a TextDocumentEdit doesn't need
+/// to sort the array of edits or do any kind of ordering. However the edits
+/// must be non overlapping.
 class TextDocumentEdit implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentEdit.canParse,
@@ -39233,8 +39973,9 @@
   }
 
   /// The edits to be applied.
-  ///  @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the
-  /// client capability `workspace.workspaceEdit.changeAnnotationSupport`
+  ///
+  /// @since 3.16.0 - support for AnnotatedTextEdit. This is guarded using a
+  /// client capability.
   final List<Either3<AnnotatedTextEdit, SnippetTextEdit, TextEdit>> edits;
 
   /// The text document to change.
@@ -39326,6 +40067,240 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+class TextDocumentFilter1 implements ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    TextDocumentFilter1.canParse,
+    TextDocumentFilter1.fromJson,
+  );
+
+  TextDocumentFilter1({
+    required this.language,
+    this.pattern,
+    this.scheme,
+  });
+  static TextDocumentFilter1 fromJson(Map<String, Object?> json) {
+    final languageJson = json['language'];
+    final language = languageJson as String;
+    final patternJson = json['pattern'];
+    final pattern = patternJson as String?;
+    final schemeJson = json['scheme'];
+    final scheme = schemeJson as String?;
+    return TextDocumentFilter1(
+      language: language,
+      pattern: pattern,
+      scheme: scheme,
+    );
+  }
+
+  /// A language id, like `typescript`. */
+  final String language;
+
+  /// A glob pattern, like `*.{ts,js}`. */
+  final String? pattern;
+
+  /// A Uri scheme, like `file` or `untitled`. */
+  final String? scheme;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    result['language'] = language;
+    if (pattern != null) {
+      result['pattern'] = pattern;
+    }
+    if (scheme != null) {
+      result['scheme'] = scheme;
+    }
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      reporter.push('language');
+      try {
+        if (!obj.containsKey('language')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final language = obj['language'];
+        if (language == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (language is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('pattern');
+      try {
+        final pattern = obj['pattern'];
+        if (pattern != null && pattern is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('scheme');
+      try {
+        final scheme = obj['scheme'];
+        if (scheme != null && scheme is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type TextDocumentFilter1');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is TextDocumentFilter1 &&
+        other.runtimeType == TextDocumentFilter1) {
+      return language == other.language &&
+          pattern == other.pattern &&
+          scheme == other.scheme &&
+          true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        language,
+        pattern,
+        scheme,
+      );
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentFilter3 implements ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    TextDocumentFilter3.canParse,
+    TextDocumentFilter3.fromJson,
+  );
+
+  TextDocumentFilter3({
+    this.language,
+    required this.pattern,
+    this.scheme,
+  });
+  static TextDocumentFilter3 fromJson(Map<String, Object?> json) {
+    final languageJson = json['language'];
+    final language = languageJson as String?;
+    final patternJson = json['pattern'];
+    final pattern = patternJson as String;
+    final schemeJson = json['scheme'];
+    final scheme = schemeJson as String?;
+    return TextDocumentFilter3(
+      language: language,
+      pattern: pattern,
+      scheme: scheme,
+    );
+  }
+
+  /// A language id, like `typescript`. */
+  final String? language;
+
+  /// A glob pattern, like `*.{ts,js}`. */
+  final String pattern;
+
+  /// A Uri scheme, like `file` or `untitled`. */
+  final String? scheme;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    if (language != null) {
+      result['language'] = language;
+    }
+    result['pattern'] = pattern;
+    if (scheme != null) {
+      result['scheme'] = scheme;
+    }
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      reporter.push('language');
+      try {
+        final language = obj['language'];
+        if (language != null && language is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('pattern');
+      try {
+        if (!obj.containsKey('pattern')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        final pattern = obj['pattern'];
+        if (pattern == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (pattern is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('scheme');
+      try {
+        final scheme = obj['scheme'];
+        if (scheme != null && scheme is! String) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type TextDocumentFilter3');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is TextDocumentFilter3 &&
+        other.runtimeType == TextDocumentFilter3) {
+      return language == other.language &&
+          pattern == other.pattern &&
+          scheme == other.scheme &&
+          true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        language,
+        pattern,
+        scheme,
+      );
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
 class TextDocumentFilterWithScheme implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentFilterWithScheme.canParse,
@@ -39335,7 +40310,7 @@
   TextDocumentFilterWithScheme({
     this.language,
     this.pattern,
-    this.scheme,
+    required this.scheme,
   });
   static TextDocumentFilterWithScheme fromJson(Map<String, Object?> json) {
     final languageJson = json['language'];
@@ -39343,7 +40318,7 @@
     final patternJson = json['pattern'];
     final pattern = patternJson as String?;
     final schemeJson = json['scheme'];
-    final scheme = schemeJson as String?;
+    final scheme = schemeJson as String;
     return TextDocumentFilterWithScheme(
       language: language,
       pattern: pattern,
@@ -39351,26 +40326,14 @@
     );
   }
 
-  /// A language id, like `typescript`.
+  /// A language id, like `typescript`. */
   final String? language;
 
-  /// A glob pattern, like `*.{ts,js}`.
-  ///
-  /// 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`)
+  /// A glob pattern, like `*.{ts,js}`. */
   final String? pattern;
 
-  /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
-  final String? scheme;
+  /// A Uri scheme, like `file` or `untitled`. */
+  final String scheme;
 
   @override
   Map<String, Object?> toJson() {
@@ -39381,9 +40344,7 @@
     if (pattern != null) {
       result['pattern'] = pattern;
     }
-    if (scheme != null) {
-      result['scheme'] = scheme;
-    }
+    result['scheme'] = scheme;
     return result;
   }
 
@@ -39411,8 +40372,16 @@
       }
       reporter.push('scheme');
       try {
+        if (!obj.containsKey('scheme')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
         final scheme = obj['scheme'];
-        if (scheme != null && scheme is! String) {
+        if (scheme == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (scheme is! String) {
           reporter.reportError('must be of type String');
           return false;
         }
@@ -39449,6 +40418,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A literal to identify a text document in the client.
 class TextDocumentIdentifier implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentIdentifier.canParse,
@@ -39473,7 +40443,7 @@
     );
   }
 
-  /// The text document's URI.
+  /// The text document's uri.
   final String uri;
 
   @override
@@ -39526,6 +40496,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// An item to transfer a text document from the client to the server.
 class TextDocumentItem implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentItem.canParse,
@@ -39561,7 +40532,7 @@
   /// The content of the opened text document.
   final String text;
 
-  /// The text document's URI.
+  /// The text document's uri.
   final String uri;
 
   /// The version number of this document (it will increase after each change,
@@ -39683,6 +40654,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A parameter literal used in requests to pass a text document and a position
+/// inside that document.
 class TextDocumentPositionParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentPositionParams.canParse,
@@ -39697,9 +40670,6 @@
     if (ReferenceParams.canParse(json, nullLspJsonReporter)) {
       return ReferenceParams.fromJson(json);
     }
-    if (RenameParams.canParse(json, nullLspJsonReporter)) {
-      return RenameParams.fromJson(json);
-    }
     if (CompletionParams.canParse(json, nullLspJsonReporter)) {
       return CompletionParams.fromJson(json);
     }
@@ -39845,10 +40815,6 @@
         json, nullLspJsonReporter)) {
       return TextDocumentChangeRegistrationOptions.fromJson(json);
     }
-    if (TextDocumentSaveRegistrationOptions.canParse(
-        json, nullLspJsonReporter)) {
-      return TextDocumentSaveRegistrationOptions.fromJson(json);
-    }
     if (CallHierarchyRegistrationOptions.canParse(json, nullLspJsonReporter)) {
       return CallHierarchyRegistrationOptions.fromJson(json);
     }
@@ -39932,6 +40898,10 @@
     if (SignatureHelpRegistrationOptions.canParse(json, nullLspJsonReporter)) {
       return SignatureHelpRegistrationOptions.fromJson(json);
     }
+    if (TextDocumentSaveRegistrationOptions.canParse(
+        json, nullLspJsonReporter)) {
+      return TextDocumentSaveRegistrationOptions.fromJson(json);
+    }
     if (TypeDefinitionRegistrationOptions.canParse(json, nullLspJsonReporter)) {
       return TypeDefinitionRegistrationOptions.fromJson(json);
     }
@@ -40043,8 +41013,9 @@
       other is TextDocumentSaveReason && other._value == _value;
 }
 
+/// Save registration options.
 class TextDocumentSaveRegistrationOptions
-    implements TextDocumentRegistrationOptions, ToJsonable {
+    implements SaveOptions, TextDocumentRegistrationOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextDocumentSaveRegistrationOptions.canParse,
     TextDocumentSaveRegistrationOptions.fromJson,
@@ -40075,6 +41046,7 @@
   final List<TextDocumentFilterWithScheme>? documentSelector;
 
   /// The client is supposed to include the content on save.
+  @override
   final bool? includeText;
 
   @override
@@ -40498,6 +41470,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A text edit applicable to a text document.
 class TextEdit implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TextEdit.canParse,
@@ -40629,6 +41602,40 @@
       other is TokenFormat && other._value == _value;
 }
 
+class TraceValues implements ToJsonable {
+  const TraceValues(this._value);
+  const TraceValues.fromJson(this._value);
+
+  final String _value;
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    return obj is String;
+  }
+
+  /// Trace messages only.
+  static const Messages = TraceValues('messages');
+
+  /// Turn tracing off.
+  static const Off = TraceValues('off');
+
+  /// Verbose message tracing.
+  static const Verbose = TraceValues('verbose');
+
+  @override
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  int get hashCode => _value.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is TraceValues && other._value == _value;
+}
+
+/// Since 3.6.0
 class TypeDefinitionClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TypeDefinitionClientCapabilities.canParse,
@@ -40656,7 +41663,8 @@
   final bool? dynamicRegistration;
 
   /// The client supports additional metadata in the form of definition links.
-  ///  @since 3.14.0
+  ///
+  /// Since 3.14.0
   final bool? linkSupport;
 
   @override
@@ -41093,6 +42101,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.17.0
 class TypeHierarchyClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TypeHierarchyClientCapabilities.canParse,
@@ -41160,6 +42169,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// @since 3.17.0
 class TypeHierarchyItem implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TypeHierarchyItem.canParse,
@@ -41228,8 +42238,7 @@
   final Range range;
 
   /// The range that should be selected and revealed when this symbol is being
-  /// picked, e.g. the name of a function. Must be contained by the
-  /// [`range`](#TypeHierarchyItem.range).
+  /// picked, e.g. the name of a function. Must be contained by the `range`.
   final Range selectionRange;
 
   /// Tags for this item.
@@ -41411,6 +42420,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Type hierarchy options used during static registration.
+///
+/// @since 3.17.0
 class TypeHierarchyOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     TypeHierarchyOptions.canParse,
@@ -41478,6 +42490,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `textDocument/prepareTypeHierarchy` request.
+///
+/// @since 3.17.0
 class TypeHierarchyPrepareParams
     implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -41614,6 +42629,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Type hierarchy options used during static or dynamic registration.
+///
+/// @since 3.17.0
 class TypeHierarchyRegistrationOptions
     implements
         StaticRegistrationOptions,
@@ -41747,6 +42765,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `typeHierarchy/subtypes` request.
+///
+/// @since 3.17.0
 class TypeHierarchySubtypesParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -41883,6 +42904,9 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// The parameter of a `typeHierarchy/supertypes` request.
+///
+/// @since 3.17.0
 class TypeHierarchySupertypesParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -42021,7 +43045,8 @@
 
 /// A diagnostic report indicating that the last returned report is still
 /// accurate.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class UnchangedDocumentDiagnosticReport implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     UnchangedDocumentDiagnosticReport.canParse,
@@ -42136,6 +43161,8 @@
 }
 
 /// Moniker uniqueness level to define scope of the moniker.
+///
+/// @since 3.16.0
 class UniquenessLevel implements ToJsonable {
   const UniquenessLevel(this._value);
   const UniquenessLevel.fromJson(this._value);
@@ -42175,7 +43202,7 @@
       other is UniquenessLevel && other._value == _value;
 }
 
-/// General parameters to unregister a capability.
+/// General parameters to unregister a request or notification.
 class Unregistration implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     Unregistration.canParse,
@@ -42201,7 +43228,7 @@
   /// provided during the register request.
   final String id;
 
-  /// The method / capability to unregister for.
+  /// The method to unregister for.
   final String method;
 
   @override
@@ -42294,9 +43321,6 @@
     );
   }
 
-  /// This should correctly be named `unregistrations`. However changing this //
-  /// is a breaking change and needs to wait until we deliver a 4.x version //
-  /// of the specification.
   final List<Unregistration> unregisterations;
 
   @override
@@ -42355,7 +43379,8 @@
 }
 
 /// A versioned notebook document identifier.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class VersionedNotebookDocumentIdentifier implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     VersionedNotebookDocumentIdentifier.canParse,
@@ -42457,6 +43482,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A text document identifier to denote a specific version of a text document.
 class VersionedTextDocumentIdentifier
     implements TextDocumentIdentifier, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -42479,14 +43505,11 @@
     );
   }
 
-  /// The text document's URI.
+  /// The text document's uri.
   @override
   final String uri;
 
   /// The version number of this document.
-  ///
-  /// The version number of a document will increase after each change,
-  /// including undo/redo. The number doesn't need to be consecutive.
   final int version;
 
   @override
@@ -42594,7 +43617,7 @@
       other is WatchKind && other._value == _value;
 }
 
-/// The parameters send in a will save text document notification.
+/// The parameters sent in a will save text document notification.
 class WillSaveTextDocumentParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WillSaveTextDocumentParams.canParse,
@@ -42728,12 +43751,14 @@
     );
   }
 
-  /// Client capabilities for the show document request.
-  ///  @since 3.16.0
+  /// Capabilities specific to the showDocument request.
+  ///
+  /// @since 3.16.0
   final ShowDocumentClientCapabilities? showDocument;
 
-  /// Capabilities specific to the showMessage request
-  ///  @since 3.16.0
+  /// Capabilities specific to the showMessage request.
+  ///
+  /// @since 3.16.0
   final ShowMessageRequestClientCapabilities? showMessage;
 
   /// It indicates whether the client supports server initiated progress using
@@ -42742,7 +43767,8 @@
   /// The capability also controls Whether client supports handling of progress
   /// notifications. If set servers are allowed to report a `workDoneProgress`
   /// property in the request specific server capabilities.
-  ///  @since 3.15.0
+  ///
+  /// @since 3.15.0
   final bool? workDoneProgress;
 
   @override
@@ -42882,7 +43908,7 @@
   /// ignore the `percentage` value in subsequent in report notifications.
   ///
   /// The value should be steadily rising. Clients are free to ignore values
-  /// that are not following this rule. The value range is [0, 100]
+  /// that are not following this rule. The value range is [0, 100].
   final int? percentage;
 
   /// Mandatory title of the progress operation. Used to briefly inform about
@@ -43427,6 +44453,9 @@
     if (InlineValueParams.canParse(json, nullLspJsonReporter)) {
       return InlineValueParams.fromJson(json);
     }
+    if (RenameParams.canParse(json, nullLspJsonReporter)) {
+      return RenameParams.fromJson(json);
+    }
     if (DocumentFormattingParams.canParse(json, nullLspJsonReporter)) {
       return DocumentFormattingParams.fromJson(json);
     }
@@ -43478,9 +44507,6 @@
     if (ReferenceParams.canParse(json, nullLspJsonReporter)) {
       return ReferenceParams.fromJson(json);
     }
-    if (RenameParams.canParse(json, nullLspJsonReporter)) {
-      return RenameParams.fromJson(json);
-    }
     if (SemanticTokensParams.canParse(json, nullLspJsonReporter)) {
       return SemanticTokensParams.fromJson(json);
     }
@@ -43627,11 +44653,10 @@
     );
   }
 
-  /// Controls enablement state of a cancel button. This property is only valid
-  /// if a cancel button got requested in the `WorkDoneProgressBegin` payload.
+  /// Controls enablement state of a cancel button.
   ///
-  /// Clients that don't support cancellation or don't support control the
-  /// button's enablement state are allowed to ignore the setting.
+  /// Clients that don't support cancellation or don't support controlling the
+  /// button's enablement state are allowed to ignore the property.
   final bool? cancellable;
   final String kind;
 
@@ -43748,6 +44773,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Workspace specific client capabilities.
 class WorkspaceClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceClientCapabilities.canParse,
@@ -43851,19 +44877,23 @@
   }
 
   /// The client supports applying batch edits to the workspace by supporting
-  /// the request 'workspace/applyEdit'
+  /// the request
+  /// 'workspace/applyEdit'
   final bool? applyEdit;
 
   /// Capabilities specific to the code lens requests scoped to the workspace.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0.
   final CodeLensWorkspaceClientCapabilities? codeLens;
 
   /// The client supports `workspace/configuration` requests.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final bool? configuration;
 
-  /// Client workspace capabilities specific to diagnostics.
-  ///  @since 3.17.0.
+  /// Capabilities specific to the diagnostic requests scoped to the workspace.
+  ///
+  /// @since 3.17.0.
   final DiagnosticWorkspaceClientCapabilities? diagnostics;
 
   /// Capabilities specific to the `workspace/didChangeConfiguration`
@@ -43877,31 +44907,38 @@
   /// Capabilities specific to the `workspace/executeCommand` request.
   final ExecuteCommandClientCapabilities? executeCommand;
 
-  /// The client has support for file requests/notifications.
-  ///  @since 3.16.0
+  /// The client has support for file notifications/requests for user operations
+  /// on files.
+  ///
+  /// Since 3.16.0
   final FileOperationClientCapabilities? fileOperations;
 
-  /// Client workspace capabilities specific to inlay hints.
-  ///  @since 3.17.0
+  /// Capabilities specific to the inlay hint requests scoped to the workspace.
+  ///
+  /// @since 3.17.0.
   final InlayHintWorkspaceClientCapabilities? inlayHint;
 
-  /// Client workspace capabilities specific to inline values.
-  ///  @since 3.17.0
+  /// Capabilities specific to the inline values requests scoped to the
+  /// workspace.
+  ///
+  /// @since 3.17.0.
   final InlineValueWorkspaceClientCapabilities? inlineValue;
 
   /// Capabilities specific to the semantic token requests scoped to the
   /// workspace.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0.
   final SemanticTokensWorkspaceClientCapabilities? semanticTokens;
 
   /// Capabilities specific to the `workspace/symbol` request.
   final WorkspaceSymbolClientCapabilities? symbol;
 
-  /// Capabilities specific to `WorkspaceEdit`s
+  /// Capabilities specific to `WorkspaceEdit`s.
   final WorkspaceEditClientCapabilities? workspaceEdit;
 
   /// The client has support for workspace folders.
-  ///  @since 3.6.0
+  ///
+  /// @since 3.6.0
   final bool? workspaceFolders;
 
   @override
@@ -44178,7 +45215,8 @@
 }
 
 /// Parameters of the workspace diagnostic request.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class WorkspaceDiagnosticParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -44345,7 +45383,8 @@
 }
 
 /// A workspace diagnostic report.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class WorkspaceDiagnosticReport implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceDiagnosticReport.canParse,
@@ -44446,7 +45485,8 @@
 }
 
 /// A partial result for a workspace diagnostic report.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class WorkspaceDiagnosticReportPartialResult implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceDiagnosticReportPartialResult.canParse,
@@ -44548,6 +45588,22 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A workspace edit represents changes to many resources managed in the
+/// workspace. The edit should either provide `changes` or `documentChanges`. If
+/// documentChanges are present they are preferred over `changes` if the client
+/// can handle versioned document edits.
+///
+/// Since version 3.13.0 a workspace edit can contain resource operations as
+/// well. If resource operations are present clients need to execute the
+/// operations in the order in which they are provided. So a workspace edit for
+/// example can consist of the following two changes:
+/// (1) a create file a.txt and (2) a text document edit which insert text into
+/// file a.txt.
+///
+/// An invalid sequence (e.g. (1) delete file a.txt and (2) insert text into
+/// file a.txt) will cause failure of the operation. How the client recovers
+/// from the failure is described by the client capability:
+/// `workspace.workspaceEdit.failureHandling`
 class WorkspaceEdit implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceEdit.canParse,
@@ -44600,7 +45656,8 @@
   ///
   /// Whether clients honor this property depends on the client capability
   /// `workspace.changeAnnotationSupport`.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final Map<String, ChangeAnnotation>? changeAnnotations;
 
   /// Holds changes to existing resources.
@@ -44771,7 +45828,8 @@
 
   /// Whether the client in general supports change annotations on text edits,
   /// create file, rename file and delete file changes.
-  ///  @since 3.16.0
+  ///
+  /// @since 3.16.0
   final WorkspaceEditClientCapabilitiesChangeAnnotationSupport?
       changeAnnotationSupport;
 
@@ -44780,18 +45838,21 @@
 
   /// The failure handling strategy of a client if applying the workspace edit
   /// fails.
-  ///  @since 3.13.0
+  ///
+  /// @since 3.13.0
   final FailureHandlingKind? failureHandling;
 
   /// Whether the client normalizes line endings to the client specific setting.
   /// If set to `true` the client will normalize line ending characters in a
-  /// workspace edit to the client specific new line character(s).
-  ///  @since 3.16.0
+  /// workspace edit to the client-specified new line character.
+  ///
+  /// @since 3.16.0
   final bool? normalizesLineEndings;
 
   /// The resource operations the client supports. Clients should at least
   /// support 'create', 'rename' and 'delete' files and folders.
-  ///  @since 3.13.0
+  ///
+  /// @since 3.13.0
   final List<ResourceOperationKind>? resourceOperations;
 
   @override
@@ -44929,8 +45990,8 @@
     );
   }
 
-  /// Whether the client groups edits with equal labels into tree nodes, for
-  /// instance all edits labelled with "Changes in Strings" would be a tree
+  /// Whether the client groups edits with equal labels into tree nodes,
+  /// for instance all edits labelled with "Changes in Strings" would be a tree
   /// node.
   final bool? groupsOnLabel;
 
@@ -44980,6 +46041,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// A workspace folder inside a client.
 class WorkspaceFolder implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceFolder.canParse,
@@ -45219,7 +46281,7 @@
 
   /// Whether the server wants to receive workspace folder change notifications.
   ///
-  /// If a string is provided, the string is treated as an ID under which the
+  /// If a string is provided the string is treated as an ID under which the
   /// notification is registered on the client side. The ID can be used to
   /// unregister for these events using the `client/unregisterCapability`
   /// request.
@@ -45294,7 +46356,8 @@
 }
 
 /// A full document diagnostic report for a workspace diagnostic result.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class WorkspaceFullDocumentDiagnosticReport
     implements FullDocumentDiagnosticReport, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -45486,9 +46549,12 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// A special workspace symbol that supports locations without a range
-///  @since 3.17.0
-class WorkspaceSymbol implements ToJsonable {
+/// A special workspace symbol that supports locations without a range.
+///
+/// See also SymbolInformation.
+///
+/// @since 3.17.0
+class WorkspaceSymbol implements BaseSymbolInformation, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceSymbol.canParse,
     WorkspaceSymbol.fromJson,
@@ -45496,6 +46562,7 @@
 
   WorkspaceSymbol({
     this.containerName,
+    this.data,
     required this.kind,
     required this.location,
     required this.name,
@@ -45504,6 +46571,8 @@
   static WorkspaceSymbol fromJson(Map<String, Object?> json) {
     final containerNameJson = json['containerName'];
     final containerName = containerNameJson as String?;
+    final dataJson = json['data'];
+    final data = dataJson;
     final kindJson = json['kind'];
     final kind = SymbolKind.fromJson(kindJson as int);
     final locationJson = json['location'];
@@ -45523,6 +46592,7 @@
         .toList();
     return WorkspaceSymbol(
       containerName: containerName,
+      data: data,
       kind: kind,
       location: location,
       name: name,
@@ -45534,22 +46604,32 @@
   /// user interface purposes (e.g. to render a qualifier in the user interface
   /// if necessary). It can't be used to re-infer a hierarchy for the document
   /// symbols.
+  @override
   final String? containerName;
 
+  /// 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;
+
   /// The kind of this symbol.
+  @override
   final SymbolKind kind;
 
-  /// The location of this symbol. Whether a server is allowed to return a
+  /// The location of the symbol. Whether a server is allowed to return a
   /// location without a range depends on the client capability
   /// `workspace.symbol.resolveSupport`.
   ///
-  /// See also `SymbolInformation.location`.
+  /// See SymbolInformation#location for more details.
   final Either2<Location, WorkspaceSymbolLocation> location;
 
   /// The name of this symbol.
+  @override
   final String name;
 
-  /// Tags for this completion item.
+  /// Tags for this symbol.
+  ///
+  /// @since 3.16.0
+  @override
   final List<SymbolTag>? tags;
 
   @override
@@ -45558,6 +46638,9 @@
     if (containerName != null) {
       result['containerName'] = containerName;
     }
+    if (data != null) {
+      result['data'] = data;
+    }
     result['kind'] = kind.toJson();
     result['location'] = location;
     result['name'] = name;
@@ -45658,6 +46741,7 @@
   bool operator ==(Object other) {
     if (other is WorkspaceSymbol && other.runtimeType == WorkspaceSymbol) {
       return containerName == other.containerName &&
+          data == other.data &&
           kind == other.kind &&
           location == other.location &&
           name == other.name &&
@@ -45670,6 +46754,7 @@
   @override
   int get hashCode => Object.hash(
         containerName,
+        data,
         kind,
         location,
         name,
@@ -45680,6 +46765,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Client capabilities for a WorkspaceSymbolRequest.
 class WorkspaceSymbolClientCapabilities implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceSymbolClientCapabilities.canParse,
@@ -45724,16 +46810,18 @@
   /// The client support partial workspace symbols. The client will send the
   /// request `workspaceSymbol/resolve` to the server to resolve additional
   /// properties.
-  ///  @since 3.17.0 - proposedState
+  ///
+  /// @since 3.17.0
   final WorkspaceSymbolClientCapabilitiesResolveSupport? resolveSupport;
 
   /// Specific capabilities for the `SymbolKind` in the `workspace/symbol`
   /// request.
   final WorkspaceSymbolClientCapabilitiesSymbolKind? symbolKind;
 
-  /// The client supports tags on `SymbolInformation` and `WorkspaceSymbol`.
-  /// Clients supporting tags have to handle unknown tags gracefully.
-  ///  @since 3.16.0
+  /// The client supports tags on `SymbolInformation`. Clients supporting tags
+  /// have to handle unknown tags gracefully.
+  ///
+  /// @since 3.16.0
   final WorkspaceSymbolClientCapabilitiesTagSupport? tagSupport;
 
   @override
@@ -46137,6 +47225,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Server capabilities for a WorkspaceSymbolRequest.
 class WorkspaceSymbolOptions implements WorkDoneProgressOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     WorkspaceSymbolOptions.canParse,
@@ -46164,7 +47253,8 @@
 
   /// The server provides support to resolve additional information for a
   /// workspace symbol.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   final bool? resolveProvider;
   @override
   final bool? workDoneProgress;
@@ -46231,7 +47321,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// The parameters of a Workspace Symbol Request.
+/// The parameters of a WorkspaceSymbolRequest.
 class WorkspaceSymbolParams
     implements PartialResultParams, WorkDoneProgressParams, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -46370,6 +47460,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Registration options for a WorkspaceSymbolRequest.
 class WorkspaceSymbolRegistrationOptions
     implements WorkspaceSymbolOptions, ToJsonable {
   static const jsonHandler = LspJsonHandler(
@@ -46395,7 +47486,8 @@
 
   /// The server provides support to resolve additional information for a
   /// workspace symbol.
-  ///  @since 3.17.0
+  ///
+  /// @since 3.17.0
   @override
   final bool? resolveProvider;
   @override
@@ -46465,7 +47557,8 @@
 }
 
 /// An unchanged document diagnostic report for a workspace diagnostic result.
-///  @since 3.17.0
+///
+/// @since 3.17.0
 class WorkspaceUnchangedDocumentDiagnosticReport
     implements UnchangedDocumentDiagnosticReport, ToJsonable {
   static const jsonHandler = LspJsonHandler(
diff --git a/pkg/analysis_server/lib/src/analytics/analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/analytics_manager.dart
index 9941bc2..3448b7b 100644
--- a/pkg/analysis_server/lib/src/analytics/analytics_manager.dart
+++ b/pkg/analysis_server/lib/src/analytics/analytics_manager.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analytics/google_analytics_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:telemetry/telemetry.dart';
@@ -38,6 +39,9 @@
   /// The server is shutting down. Report any accumulated analytics data.
   void shutdown();
 
+  /// Record data from the given [params].
+  void startedGetRefactoring(EditGetRefactoringParams params);
+
   /// Record that the server started working on the give [request] at the given
   /// [startTime].
   void startedRequest({required Request request, required DateTime startTime});
@@ -47,6 +51,12 @@
   void startedRequestMessage(
       {required RequestMessage request, required DateTime startTime});
 
+  /// Record data from the given [params].
+  void startedSetAnalysisRoots(AnalysisSetAnalysisRootsParams params);
+
+  /// Record data from the given [params].
+  void startedSetPriorityFiles(AnalysisSetPriorityFilesParams params);
+
   /// Record that the server was started at the given [time], that it was passed
   /// the given command-line [arguments], that it was started by the client with
   /// the given [clientId] and [clientVersion], and that it was invoked from an
diff --git a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
index ddeef8c..f294c37 100644
--- a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
+++ b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
@@ -5,10 +5,11 @@
 import 'dart:convert';
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analytics/analytics_manager.dart';
 import 'package:analysis_server/src/analytics/percentile_calculator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:telemetry/telemetry.dart';
 
 /// An implementation of [AnalyticsManager] that's appropriate to use when
@@ -93,9 +94,19 @@
   }
 
   @override
+  void startedGetRefactoring(EditGetRefactoringParams params) {
+    var requestData = _completedRequests.putIfAbsent(
+        EDIT_REQUEST_GET_REFACTORING,
+        () => _RequestData(EDIT_REQUEST_GET_REFACTORING));
+    requestData.addEnumValue(
+        EDIT_REQUEST_GET_REFACTORING_KIND, params.kind.name);
+  }
+
+  @override
   void startedRequest({required Request request, required DateTime startTime}) {
-    _activeRequests[request.id] = _ActiveRequestData(
-        request.method, request.clientRequestTime, startTime);
+    var method = request.method;
+    _activeRequests[request.id] =
+        _ActiveRequestData(method, request.clientRequestTime, startTime);
   }
 
   @override
@@ -106,6 +117,26 @@
   }
 
   @override
+  void startedSetAnalysisRoots(AnalysisSetAnalysisRootsParams params) {
+    var requestData = _completedRequests.putIfAbsent(
+        ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS,
+        () => _RequestData(ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS));
+    requestData.addValue(
+        ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_INCLUDED, params.included.length);
+    requestData.addValue(
+        ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_EXCLUDED, params.excluded.length);
+  }
+
+  @override
+  void startedSetPriorityFiles(AnalysisSetPriorityFilesParams params) {
+    var requestData = _completedRequests.putIfAbsent(
+        ANALYSIS_REQUEST_SET_PRIORITY_FILES,
+        () => _RequestData(ANALYSIS_REQUEST_SET_PRIORITY_FILES));
+    requestData.addValue(
+        ANALYSIS_REQUEST_SET_PRIORITY_FILES_FILES, params.files.length);
+  }
+
+  @override
   void startUp(
       {required DateTime time,
       required List<String> arguments,
@@ -128,12 +159,12 @@
       return;
     }
 
-    var requestName = data.requestName;
+    var method = data.method;
     var clientRequestTime = data.clientRequestTime;
     var startTime = data.startTime.millisecondsSinceEpoch;
 
-    var requestData = _completedRequests.putIfAbsent(
-        requestName, () => _RequestData(requestName));
+    var requestData =
+        _completedRequests.putIfAbsent(method, () => _RequestData(method));
 
     if (clientRequestTime != null) {
       var latencyTime = startTime - clientRequestTime;
@@ -176,6 +207,10 @@
         'latency': data.latencyTimes.toAnalyticsString(),
         'method': data.method,
         'duration': data.responseTimes.toAnalyticsString(),
+        for (var field in data.additionalPercentiles.entries)
+          field.key: field.value.toAnalyticsString(),
+        for (var field in data.additionalEnumCounts.entries)
+          field.key: json.encode(field.value),
       });
     }
   }
@@ -198,7 +233,7 @@
 /// Data about a request that was received and is being handled.
 class _ActiveRequestData {
   /// The name of the request that was received.
-  final String requestName;
+  final String method;
 
   /// The time at which the client sent the request.
   final int? clientRequestTime;
@@ -207,7 +242,7 @@
   final DateTime startTime;
 
   /// Initialize a newly created data holder.
-  _ActiveRequestData(this.requestName, this.clientRequestTime, this.startTime);
+  _ActiveRequestData(this.method, this.clientRequestTime, this.startTime);
 }
 
 /// Data about the notifications that have been handled that have the same
@@ -289,9 +324,33 @@
   /// the response was sent.
   final PercentileCalculator responseTimes = PercentileCalculator();
 
+  /// A table mapping the names of fields in a request's parameters to the
+  /// percentile calculators related to the value of the parameter (such as the
+  /// length of a list).
+  final Map<String, PercentileCalculator> additionalPercentiles = {};
+
+  /// A table mapping the name of a field in a request's parameters and the name
+  /// of an enum constant to the number of times that the given constant was
+  /// used as the value of the field.
+  final Map<String, Map<String, int>> additionalEnumCounts = {};
+
   /// Initialize a newly create data holder for requests with the given
   /// [method].
   _RequestData(this.method);
+
+  /// Record the occurrence of the enum constant with the given [enumName] for
+  /// the field with the given [name].
+  void addEnumValue<E>(String name, String enumName) {
+    var counts = additionalEnumCounts.putIfAbsent(name, () => {});
+    counts[enumName] = (counts[enumName] ?? 0) + 1;
+  }
+
+  /// Record a [value] for the field with the given [name].
+  void addValue(String name, int value) {
+    additionalPercentiles
+        .putIfAbsent(name, PercentileCalculator.new)
+        .addValue(value);
+  }
 }
 
 /// Data about the current session.
diff --git a/pkg/analysis_server/lib/src/analytics/noop_analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/noop_analytics_manager.dart
index 0c08132..3302a1e 100644
--- a/pkg/analysis_server/lib/src/analytics/noop_analytics_manager.dart
+++ b/pkg/analysis_server/lib/src/analytics/noop_analytics_manager.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analytics/analytics_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 
@@ -29,6 +30,9 @@
   void shutdown() {}
 
   @override
+  void startedGetRefactoring(EditGetRefactoringParams params) {}
+
+  @override
   void startedRequest(
       {required Request request, required DateTime startTime}) {}
 
@@ -37,6 +41,12 @@
       {required RequestMessage request, required DateTime startTime}) {}
 
   @override
+  void startedSetAnalysisRoots(AnalysisSetAnalysisRootsParams params) {}
+
+  @override
+  void startedSetPriorityFiles(AnalysisSetPriorityFilesParams params) {}
+
+  @override
   void startUp(
       {required DateTime time,
       required List<String> arguments,
diff --git a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_analysis_roots.dart b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_analysis_roots.dart
index 01ef88f..6f2c5e2 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_analysis_roots.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_analysis_roots.dart
@@ -23,6 +23,7 @@
 
     server.options.analytics?.sendEvent('analysis', 'setAnalysisRoots',
         value: includedPathList.length);
+    server.analyticsManager.startedSetAnalysisRoots(params);
 
     // validate
     for (var path in includedPathList) {
diff --git a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
index 90fc2e5..55dc519 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
@@ -20,6 +20,8 @@
   Future<void> handle() async {
     var params = AnalysisSetPriorityFilesParams.fromRequest(request);
 
+    server.analyticsManager.startedSetPriorityFiles(params);
+
     for (var file in params.files) {
       if (!server.isAbsoluteAndNormalized(file)) {
         sendResponse(Response.invalidFilePathFormat(request, file));
diff --git a/pkg/analysis_server/lib/src/handler/legacy/edit_get_refactoring.dart b/pkg/analysis_server/lib/src/handler/legacy/edit_get_refactoring.dart
index f4793ce..61e7d3a 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/edit_get_refactoring.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/edit_get_refactoring.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 
 /// The handler for the `edit.getRefactoring` request.
@@ -16,12 +17,16 @@
 
   @override
   Future<void> handle() async {
+    var params = EditGetRefactoringParams.fromRequest(request);
+
+    server.analyticsManager.startedGetRefactoring(params);
+
     final refactoringManager = server.refactoringManager;
     if (refactoringManager == null) {
       sendResponse(
           Response.unsupportedFeature(request.id, 'Search is not enabled.'));
       return;
     }
-    refactoringManager.getRefactoring(request, cancellationToken);
+    refactoringManager.getRefactoring(request, params, cancellationToken);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/abstract_refactor.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/abstract_refactor.dart
index 414d320..561cd23 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/abstract_refactor.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/abstract_refactor.dart
@@ -19,7 +19,8 @@
 
 /// A base class for refactoring commands that need to create Refactorings from
 /// client-supplied arguments.
-abstract class AbstractRefactorCommandHandler extends SimpleEditCommandHandler {
+abstract class AbstractRefactorCommandHandler extends SimpleEditCommandHandler
+    with PositionalArgCommandHandler {
   AbstractRefactorCommandHandler(super.server);
 
   @override
@@ -138,39 +139,60 @@
   }
 
   @override
-  Future<ErrorOr<void>> handle(List<Object?>? arguments,
+  Future<ErrorOr<void>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken) async {
-    if (arguments == null ||
-        arguments.length != 6 ||
-        arguments[0] is! String || // kind
-        arguments[1] is! String || // path
-        (arguments[2] != null && arguments[2] is! int) || // docVersion
-        arguments[3] is! int || // offset
-        arguments[4] is! int || // length
-        // options
-        // Important: This arguments position is documented in
-        // tool/lsp_spec/README.md to allow clients with custom code (such as
-        // VS Code) to intercept the request and inject options (such as a
-        // user-provided name). Any changes to these arguments must be backwards
-        // compatible, keeping the options in this position.
-        (arguments[5] != null && arguments[5] is! Map<String, Object?>)) {
+    if (parameters['kind'] is! String ||
+        parameters['path'] is! String ||
+        (parameters['docVersion'] is! int?) ||
+        parameters['offset'] is! int ||
+        parameters['length'] is! int ||
+        (parameters['options'] is! Map<String, Object?>?)) {
       return ErrorOr.error(ResponseError(
         code: ServerErrorCodes.InvalidCommandArguments,
-        message:
-            '$commandName requires 6 parameters: RefactoringKind, docVersion, filePath, offset, length, options (optional)',
+        message: '$commandName requires 6 parameters: '
+            'kind: String (RefactoringKind), '
+            'filePath: String, '
+            'docVersion: int?, '
+            'offset: int, '
+            'length: int, '
+            'options: Map<String, Object?>',
       ));
     }
 
-    final kind = arguments[0] as String;
-    final path = arguments[1] as String;
-    final docVersion = arguments[2] as int?;
-    final offset = arguments[3] as int;
-    final length = arguments[4] as int;
-    final options = arguments[5] as Map<String, Object?>?;
+    final kind = parameters['kind'] as String;
+    final path = parameters['path'] as String;
+    final docVersion = parameters['docVersion'] as int?;
+    final offset = parameters['offset'] as int;
+    final length = parameters['length'] as int;
+    final options = parameters['options'] as Map<String, Object?>?;
 
     return execute(path, kind, offset, length, options, cancellationToken,
         progress, docVersion);
   }
+
+  /// Parses "legacy" arguments passed a list, rather than in a map as a single
+  /// argument.
+  ///
+  /// This is provided for backwards compatibility and is only supported by
+  /// handlers intended to be called by clients with their own built arguments.
+  @override
+  Map<String, Object?> parseArgList(List<Object?> arguments) {
+    if (arguments.length != 6) {
+      return {};
+    }
+
+    return {
+      'kind': arguments[0],
+      'path': arguments[1],
+      'docVersion': arguments[2],
+      'offset': arguments[3],
+      'length': arguments[4],
+      // options
+      // This field is overwritten (by index) by Dart-Code (older versions that
+      // are not using Maps) so the index of this item must not change.
+      'options': arguments[5],
+    };
+  }
 }
 
 /// Manages a running refactor to help ensure only one refactor runs at a time.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all.dart
index 6d0bdba..b108a4e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all.dart
@@ -18,20 +18,19 @@
   String get commandName => 'Fix All';
 
   @override
-  Future<ErrorOr<void>> handle(List<Object?>? arguments,
+  Future<ErrorOr<void>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken) async {
-    if (arguments == null || arguments.length != 1 || arguments[0] is! String) {
+    if (parameters['path'] is! String) {
       return ErrorOr.error(ResponseError(
         code: ServerErrorCodes.InvalidCommandArguments,
-        message:
-            '$commandName requires a single String parameter containing the path of a Dart file',
+        message: '$commandName requires a Map argument containing a "path"',
       ));
     }
 
     // Get the version of the doc before we calculate edits so we can send it back
     // to the client so that they can discard this edit if the document has been
     // modified since.
-    final path = arguments.single as String;
+    final path = parameters['path'] as String;
     final docIdentifier = server.getVersionedDocumentIdentifier(path);
 
     final result = await requireResolvedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index e7e89cc..7c0211b 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -16,20 +16,19 @@
   String get commandName => 'Organize Imports';
 
   @override
-  Future<ErrorOr<void>> handle(List<Object?>? arguments,
+  Future<ErrorOr<void>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken) async {
-    if (arguments == null || arguments.length != 1 || arguments[0] is! String) {
+    if (parameters['path'] is! String) {
       return ErrorOr.error(ResponseError(
         code: ServerErrorCodes.InvalidCommandArguments,
-        message:
-            '$commandName requires a single String parameter containing the path of a Dart file',
+        message: '$commandName requires a Map argument containing a "path"',
       ));
     }
 
     // Get the version of the doc before we calculate edits so we can send it back
     // to the client so that they can discard this edit if the document has been
     // modified since.
-    final path = arguments.single as String;
+    final path = parameters['path'] as String;
     final docIdentifier = server.getVersionedDocumentIdentifier(path);
 
     final result = await requireResolvedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
index a430214..62a27dc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
@@ -22,20 +22,18 @@
   String get commandName => 'Send Workspace Edit';
 
   @override
-  Future<ErrorOr<void>> handle(List<Object?>? arguments,
+  Future<ErrorOr<void>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken) async {
-    if (arguments == null ||
-        arguments.length != 1 ||
-        arguments[0] is! Map<String, Object?>) {
+    if (parameters['edit'] is! Map<String, Object?>) {
       return ErrorOr.error(ResponseError(
         code: ServerErrorCodes.InvalidCommandArguments,
         message:
-            '$commandName requires a single List argument of WorkspaceEdit',
+            '$commandName requires a Map argument containing "edit" (WorkspaceEdit)',
       ));
     }
 
     final workspaceEdit =
-        WorkspaceEdit.fromJson(arguments[0] as Map<String, Object?>);
+        WorkspaceEdit.fromJson(parameters['edit'] as Map<String, Object?>);
 
     return await sendWorkspaceEditToClient(workspaceEdit);
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
index b008673..c2ec845 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
@@ -17,20 +17,19 @@
   String get commandName => 'Sort Members';
 
   @override
-  Future<ErrorOr<void>> handle(List<Object?>? arguments,
+  Future<ErrorOr<void>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken) async {
-    if (arguments == null || arguments.length != 1 || arguments[0] is! String) {
+    if (parameters['path'] is! String) {
       return ErrorOr.error(ResponseError(
         code: ServerErrorCodes.InvalidCommandArguments,
-        message:
-            '$commandName requires a single String parameter containing the path of a Dart file',
+        message: '$commandName requires a Map argument containing a "path"',
       ));
     }
 
     // Get the version of the doc before we calculate edits so we can send it back
     // to the client so that they can discard this edit if the document has been
     // modified since.
-    final path = arguments.single as String;
+    final path = parameters['path'] as String;
     final docIdentifier = server.getVersionedDocumentIdentifier(path);
 
     var session = await server.getAnalysisSession(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 82d2c4b..479d155 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -345,6 +345,8 @@
     int length,
     ResolvedUnitResult unit,
   ) async {
+    final docIdentifier = server.getVersionedDocumentIdentifier(path);
+
     final results = await Future.wait([
       if (shouldIncludeAnyOfKind(CodeActionKind.Source))
         performance.runAsync(
@@ -362,8 +364,8 @@
       if (shouldIncludeAnyOfKind(CodeActionKind.Refactor))
         performance.runAsync(
           '_getRefactorActions',
-          (_) => _getRefactorActions(
-              shouldIncludeKind, supportsLiterals, path, offset, length, unit),
+          (_) => _getRefactorActions(shouldIncludeKind, supportsLiterals, path,
+              docIdentifier, offset, length, unit),
         ),
       if (shouldIncludeAnyOfKind(CodeActionKind.QuickFix))
         performance.runAsync(
@@ -520,6 +522,7 @@
     bool Function(CodeActionKind) shouldIncludeKind,
     bool supportsLiteralCodeActions,
     String path,
+    OptionalVersionedTextDocumentIdentifier docIdentifier,
     int offset,
     int length,
     ResolvedUnitResult unit,
@@ -545,6 +548,9 @@
             title: name,
             command: Commands.performRefactor,
             arguments: [
+              // TODO(dantup): Change this to a Map once Dart-Code is updated
+              //   to handle both Maps and Lists (and some reasonable time has
+              //   passed to not worry about old versions).
               refactorKind.toJson(),
               path,
               server.getVersionedDocumentIdentifier(path).version,
@@ -659,7 +665,9 @@
           Command(
               title: 'Sort Members',
               command: Commands.sortMembers,
-              arguments: [path]),
+              arguments: [
+                {'path': path}
+              ]),
         ),
       if (shouldIncludeKind(CodeActionKind.SourceOrganizeImports))
         _commandOrCodeAction(
@@ -668,14 +676,21 @@
           Command(
               title: 'Organize Imports',
               command: Commands.organizeImports,
-              arguments: [path]),
+              arguments: [
+                {'path': path}
+              ]),
         ),
       if (shouldIncludeKind(DartCodeActionKind.FixAll))
         _commandOrCodeAction(
           supportsLiteralCodeActions,
           DartCodeActionKind.FixAll,
           Command(
-              title: 'Fix All', command: Commands.fixAll, arguments: [path]),
+            title: 'Fix All',
+            command: Commands.fixAll,
+            arguments: [
+              {'path': path}
+            ],
+          ),
         ),
     ];
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
index 772eb6b..d9c3f09 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -113,7 +113,9 @@
           command = Command(
               title: 'Add import',
               command: Commands.sendWorkspaceEdit,
-              arguments: [workspaceEdit]);
+              arguments: [
+                {'edit': workspaceEdit}
+              ]);
         }
 
         final formats = clientCapabilities.completionDocumentationFormats;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
index 6a2cf7e..e75e0f1 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
@@ -51,6 +51,26 @@
         : server.clientCapabilities?.workDoneProgress ?? false
             ? ProgressReporter.serverCreated(server)
             : ProgressReporter.noop;
-    return handler.handle(params.arguments, progress, token);
+
+    // To make parsing arguments easier in commands, instead of a
+    // `List<Object?>` we now use `Map<String, Object?>`.
+    //
+    // However, some handlers still support the list for compatibility so we
+    // must allow the to convert a `List` to a `Map`.
+    final arguments = params.arguments ?? const [];
+    Map<String, Object?> commandParams;
+    if (arguments.length == 1 && arguments[0] is Map<String, Object?>) {
+      commandParams = arguments.single as Map<String, Object?>;
+    } else if (handler is PositionalArgCommandHandler) {
+      final argHandler = handler as PositionalArgCommandHandler;
+      commandParams = argHandler.parseArgList(arguments);
+    } else {
+      return ErrorOr.error(ResponseError(
+        code: ServerErrorCodes.InvalidCommandArguments,
+        message: '${params.command} requires a single Map argument',
+      ));
+    }
+
+    return handler.handle(commandParams, progress, token);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index c283fd2..c73c919 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -11,8 +11,13 @@
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analyzer/dart/element/element.dart';
 
+// TODO(dantup): Generate typedefs in protocol_generated for all named types
+//   that map onto unions like this after the switch to JSON spec.
+typedef PrepareRenameResult
+    = Either3<Range, PlaceholderAndRange, PrepareRenameResult2>;
+
 class PrepareRenameHandler
-    extends MessageHandler<TextDocumentPositionParams, PlaceholderAndRange?> {
+    extends MessageHandler<TextDocumentPositionParams, PrepareRenameResult?> {
   PrepareRenameHandler(super.server);
   @override
   Method get handlesMessage => Method.textDocument_prepareRename;
@@ -22,7 +27,7 @@
       TextDocumentPositionParams.jsonHandler;
 
   @override
-  Future<ErrorOr<PlaceholderAndRange?>> handle(
+  Future<ErrorOr<PrepareRenameResult?>> handle(
       TextDocumentPositionParams params,
       MessageInfo message,
       CancellationToken token) async {
@@ -61,7 +66,7 @@
             ServerErrorCodes.RenameNotValid, initStatus.problem!.message, null);
       }
 
-      return success(PlaceholderAndRange(
+      return success(PrepareRenameResult.t2(PlaceholderAndRange(
         range: toRange(
           unit.result.lineInfo,
           // If the offset is set to -1 it means there is no location for the
@@ -72,7 +77,7 @@
           refactorDetails.length,
         ),
         placeholder: refactoring.oldName,
-      ));
+      )));
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index faca1ad..6f2bea3 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -36,7 +36,7 @@
 
   CommandHandler(this.server);
 
-  Future<ErrorOr<Object?>> handle(List<Object?>? arguments,
+  Future<ErrorOr<Object?>> handle(Map<String, Object?> parameters,
       ProgressReporter progress, CancellationToken cancellationToken);
 }
 
@@ -199,6 +199,15 @@
   MessageInfo({required this.performance, this.timeSinceRequest});
 }
 
+mixin PositionalArgCommandHandler {
+  /// Parses "legacy" arguments passed a list, rather than in a map as a single
+  /// argument.
+  ///
+  /// This is provided for backwards compatibility and may not be provided by
+  /// all command handlers.
+  Map<String, Object?> parseArgList(List<Object?> arguments);
+}
+
 /// A message handler that handles all messages for a given server state.
 abstract class ServerStateMessageHandler {
   final LspAnalysisServer server;
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index d7db246..db49280 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -973,7 +973,9 @@
     command = Command(
         title: 'Add import',
         command: Commands.sendWorkspaceEdit,
-        arguments: [workspaceEdit]);
+        arguments: [
+          {'edit': workspaceEdit}
+        ]);
   }
 
   /// Convert the changes to TextEdits using snippet tokens for linked edit
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 05fdc77..276a876 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -78,6 +78,9 @@
     CompileTimeErrorCode.UNDEFINED_CLASS: [
       DataDriven.new,
     ],
+    CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER: [
+      DataDriven.new,
+    ],
     CompileTimeErrorCode.UNDEFINED_FUNCTION: [
       DataDriven.new,
     ],
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
index c8f71ce..17b3c2c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
@@ -25,7 +25,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = coveredNode;
+    var node = coveredNode?.parent;
     if (node is! SwitchCase) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 18b6ea6..ce4c488 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -1653,6 +1653,8 @@
   status: hasFix
 LintCode.directives_ordering:
   status: hasFix
+LintCode.discarded_futures:
+  status: needsEvaluation
 LintCode.do_not_use_environment:
   status: needsEvaluation
 LintCode.empty_catches:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart
index d690c0b..a8d459b 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart
@@ -27,6 +27,11 @@
   void apply(DartFileEditBuilder builder, DataDrivenFix fix, _Data data) {
     var referenceRange = data.referenceRange;
     builder.addSimpleReplacement(referenceRange, _referenceTo(newElement));
+    var libraryUris = newElement.libraryUris;
+    if (libraryUris.isEmpty) return;
+    if (!libraryUris.any((uri) => builder.importsLibrary(uri))) {
+      builder.importLibraryElement(libraryUris.first);
+    }
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_manager.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_manager.dart
index e54b148..bcc0341 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_manager.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_manager.dart
@@ -91,15 +91,15 @@
     _reset();
   }
 
-  void getRefactoring(Request request, CancellationToken cancellationToken) {
+  void getRefactoring(Request request, EditGetRefactoringParams params,
+      CancellationToken cancellationToken) {
     // prepare for processing the request
     this.request = request;
     final result = this.result = EditGetRefactoringResult(
         EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST);
-    // process the request
-    var params = EditGetRefactoringParams.fromRequest(request);
-    var file = params.file;
 
+    // process the request
+    var file = params.file;
     if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index 4eef36f..3d228b7 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
@@ -25,7 +25,12 @@
           throw 'Got Command but expected CodeAction literal';
         }
         expect(command.title, equals(title));
-        expect(command.arguments, equals([uri.toFilePath()]));
+        expect(
+          command.arguments,
+          equals([
+            {'path': uri.toFilePath()}
+          ]),
+        );
       },
       (codeAction) {
         if (!asCodeActionLiteral) {
@@ -33,7 +38,12 @@
         }
         expect(codeAction.title, equals(title));
         expect(codeAction.command!.title, equals(title));
-        expect(codeAction.command!.arguments, equals([uri.toFilePath()]));
+        expect(
+          codeAction.command!.arguments,
+          equals([
+            {'path': uri.toFilePath()}
+          ]),
+        );
       },
     );
   }
diff --git a/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
index 453956b..ec74340 100644
--- a/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
+++ b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
@@ -5,10 +5,11 @@
 import 'dart:convert';
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analytics/google_analytics_manager.dart';
 import 'package:analysis_server/src/analytics/percentile_calculator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/analysis/context_root.dart' as analyzer;
 import 'package:telemetry/telemetry.dart';
 import 'package:test/test.dart';
@@ -62,17 +63,81 @@
     ]);
   }
 
-  void test_server_request() {
+  void test_server_request_analysisSetAnalysisRoots() {
     _defaultStartup();
-    manager.startedRequest(
-        request: Request('1', 'server.shutdown'), startTime: _now());
+    var params = AnalysisSetAnalysisRootsParams(['a', 'b', 'c'], ['d', 'e']);
+    var request =
+        Request('1', ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS, params.toJson());
+    manager.startedRequest(request: request, startTime: _now());
+    manager.startedSetAnalysisRoots(params);
     manager.sentResponse(response: Response('1'));
     manager.shutdown();
     analytics.assertEvents([
       _ExpectedEvent.session(),
       _ExpectedEvent.request(parameters: {
         'latency': _IsPercentiles(),
-        'method': 'server.shutdown',
+        'method': ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS,
+        'duration': _IsPercentiles(),
+        ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_INCLUDED:
+            '{"count":1,"percentiles":[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]}',
+        ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_EXCLUDED:
+            '{"count":1,"percentiles":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]}',
+      }),
+    ]);
+  }
+
+  void test_server_request_analysisSetPriorityFiles() {
+    _defaultStartup();
+    var params = AnalysisSetPriorityFilesParams(['a']);
+    var request =
+        Request('1', ANALYSIS_REQUEST_SET_PRIORITY_FILES, params.toJson());
+    manager.startedRequest(request: request, startTime: _now());
+    manager.startedSetPriorityFiles(params);
+    manager.sentResponse(response: Response('1'));
+    manager.shutdown();
+    analytics.assertEvents([
+      _ExpectedEvent.session(),
+      _ExpectedEvent.request(parameters: {
+        'latency': _IsPercentiles(),
+        'method': ANALYSIS_REQUEST_SET_PRIORITY_FILES,
+        'duration': _IsPercentiles(),
+        ANALYSIS_REQUEST_SET_PRIORITY_FILES_FILES:
+            '{"count":1,"percentiles":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}',
+      }),
+    ]);
+  }
+
+  void test_server_request_editGetRefactoring() {
+    _defaultStartup();
+    var params =
+        EditGetRefactoringParams(RefactoringKind.RENAME, '', 0, 0, true);
+    var request = Request('1', EDIT_REQUEST_GET_REFACTORING, params.toJson());
+    manager.startedRequest(request: request, startTime: _now());
+    manager.startedGetRefactoring(params);
+    manager.sentResponse(response: Response('1'));
+    manager.shutdown();
+    analytics.assertEvents([
+      _ExpectedEvent.session(),
+      _ExpectedEvent.request(parameters: {
+        'latency': _IsPercentiles(),
+        'method': EDIT_REQUEST_GET_REFACTORING,
+        'duration': _IsPercentiles(),
+        EDIT_REQUEST_GET_REFACTORING_KIND: '{"RENAME":1}',
+      }),
+    ]);
+  }
+
+  void test_server_request_noAdditional() {
+    _defaultStartup();
+    manager.startedRequest(
+        request: Request('1', SERVER_REQUEST_SHUTDOWN), startTime: _now());
+    manager.sentResponse(response: Response('1'));
+    manager.shutdown();
+    analytics.assertEvents([
+      _ExpectedEvent.session(),
+      _ExpectedEvent.request(parameters: {
+        'latency': _IsPercentiles(),
+        'method': SERVER_REQUEST_SHUTDOWN,
         'duration': _IsPercentiles(),
       }),
     ]);
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
index 35e01af..b5d3b6f 100644
--- a/pkg/analysis_server/test/src/cider/cider_service.dart
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -43,7 +43,7 @@
       getFileDigest: (String path) => _getDigest(path),
       prefetchFiles: null,
       workspace: workspace,
-      byteStore: CiderCachedByteStore(20 * 1024 * 1024 /* 20 MB */),
+      byteStore: MemoryCiderByteStore(),
     );
     fileResolver.testView = FileResolverTestView();
   }
diff --git a/pkg/analysis_server/test/src/computer/color_computer_test.dart b/pkg/analysis_server/test/src/computer/color_computer_test.dart
index 159d18e..c7b63c2 100644
--- a/pkg/analysis_server/test/src/computer/color_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/color_computer_test.dart
@@ -38,6 +38,7 @@
     'Color(0xFF0000FF)': 0xFF0000FF,
     'Color.fromARGB(255, 0, 0, 255)': 0xFF0000FF,
     'Color.fromRGBO(0, 0, 255, 1)': 0xFF0000FF,
+    'Color.fromRGBO(0, 0, 255, 1.0)': 0xFF0000FF,
     // Flutter Painting
     'ColorSwatch(0xFF89ABCD, {})': 0xFF89ABCD,
     // Flutter Material
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart
index a7b70a4..b4643f2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart
@@ -14,6 +14,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ReplacedByTest);
+    defineReflectiveTests(ReplacedByUriSemanticsTest);
   });
 }
 
@@ -862,6 +863,83 @@
   }
 }
 
+@reflectiveTest
+class ReplacedByUriSemanticsTest extends DataDrivenFixProcessorTest {
+  Future<void> test_new_element_uris_multiple() async {
+    setPackageContent('');
+    newFile('$workspaceRootPath/p/lib/expect.dart', '''
+void expect(actual, expected) {}
+''');
+    newFile('$workspaceRootPath/p/lib/export.dart', '''
+export 'expect.dart';
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title:  'Replace expect'
+    date: 2022-05-12
+    bulkApply: false
+    element:
+      uris: ['$importUri']
+      function: 'expect'
+    changes:
+      - kind: 'replacedBy'
+        newElement:
+          uris: ['package:p/expect.dart', 'package:p/export.dart']
+          function: 'expect'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+f() {
+  expect(true, true);
+}
+''');
+    await assertHasFix('''
+import 'package:p/expect.dart';
+import '$importUri';
+
+f() {
+  expect(true, true);
+}
+''', errorFilter: ignoreUnusedImport);
+  }
+
+  Future<void> test_new_element_uris_single() async {
+    setPackageContent('');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title:  'Replace expect'
+    date: 2022-05-12
+    bulkApply: false
+    element:
+      uris: ['$importUri']
+      function: 'expect'
+    changes:
+      - kind: 'replacedBy'
+        newElement:
+          uris: ['package:matcher/expect.dart']
+          function: 'expect'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''');
+    await assertHasFix('''
+import 'package:matcher/expect.dart';
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''', errorFilter: ignoreUnusedImport);
+  }
+}
+
 class _Element {
   final ElementKind kind;
   final List<String> components;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
index 544f27c..f9623c1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
@@ -17,6 +17,7 @@
 import 'rename_test.dart' as rename;
 import 'replaced_by_test.dart' as replaced_by;
 import 'sdk_fix_test.dart' as sdk_fix;
+import 'test_use_case_test.dart' as test_use_case;
 import 'transform_override_set_parser_test.dart'
     as transform_override_set_parser;
 import 'transform_set_manager_test.dart' as transform_set_manager;
@@ -37,6 +38,7 @@
     rename.main();
     replaced_by.main();
     sdk_fix.main();
+    test_use_case.main();
     transform_override_set_parser.main();
     transform_set_manager.main();
     transform_set_parser.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_use_case_test.dart
new file mode 100644
index 0000000..aa0386b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_use_case_test.dart
@@ -0,0 +1,102 @@
+// 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../fix_processor.dart';
+import 'data_driven_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TestUseCaseTest);
+  });
+}
+
+@reflectiveTest
+class TestUseCaseTest extends DataDrivenFixProcessorTest {
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/23067')
+  Future<void> test_expect_export_deprecated() async {
+    newFile('$workspaceRootPath/p/lib/lib.dart', '''
+library p;
+@deprecated
+export 'package:matcher/expect.dart' show expect;
+''');
+    newFile('$workspaceRootPath/matcher/lib/expect.dart', '''
+void expect(actual, matcher) {}
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'matcher', rootPath: '$workspaceRootPath/matcher')
+        ..add(name: 'p', rootPath: '$workspaceRootPath/p'),
+    );
+
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title:  'Replace expect'
+    date: 2022-05-12
+    bulkApply: false
+    element:
+      uris: ['$importUri']
+      function: 'expect'
+    changes:
+      - kind: 'replacedBy'
+        newElement:
+          uris: ['package:matcher/expect.dart']
+          function: 'expect'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''');
+    await assertHasFix('''
+import 'package:matcher/expect.dart';
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''');
+  }
+
+  Future<void> test_expect_removed() async {
+    setPackageContent('''
+''');
+
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title:  'Replace expect'
+    date: 2022-05-12
+    bulkApply: false
+    element:
+      uris: ['$importUri']
+      function: 'expect'
+    changes:
+      - kind: 'replacedBy'
+        newElement:
+          uris: ['package:matcher/expect.dart']
+          function: 'expect'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''');
+    await assertHasFix('''
+import 'package:matcher/expect.dart';
+import '$importUri';
+
+main() {
+  expect(true, true);
+}
+''', errorFilter: ignoreUnusedImport);
+  }
+}
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 0093cff..7384167 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test/test.dart';
 
-import '../../../tool/lsp_spec/typescript_parser.dart' as ast;
+import '../../../tool/lsp_spec/meta_model.dart' as ast;
 
 void main() {
   group('dartType mapping', () {
@@ -30,8 +30,7 @@
 
 ast.ArrayType _array(String name) => ast.ArrayType(_simple(name));
 
-ast.Type _simple(String name) =>
-    ast.Type(ast.Token(ast.TokenType.IDENTIFIER, name), []);
+ast.TypeReference _simple(String name) => ast.TypeReference(name);
 
 ast.UnionType _union(List<String> names) =>
     ast.UnionType(names.map(_simple).toList());
diff --git a/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart b/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart
deleted file mode 100644
index bf968e7..0000000
--- a/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2018, 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 'package:test/test.dart';
-
-import '../../../tool/lsp_spec/markdown.dart';
-
-void main() {
-  group('markdown parser', () {
-    test('extracts a typescript fenced block from Markdown', () {
-      final input = '''
-```typescript
-CONTENT
-```
-    ''';
-      final output = extractTypeScriptBlocks(input);
-      expect(output, hasLength(1));
-      expect(output, contains('CONTENT'));
-    });
-
-    test('does not extract unknown code blocks', () {
-      final input = '''
-```
-CONTENT
-```
-
-```dart
-CONTENT
-```
-    ''';
-      final output = extractTypeScriptBlocks(input);
-      expect(output, hasLength(0));
-    });
-
-    test('extracts multiple code blocks', () {
-      final input = '''
-```typescript
-CONTENT1
-```
-
-```typescript
-CONTENT2
-```
-    ''';
-      final output = extractTypeScriptBlocks(input);
-      expect(output, hasLength(2));
-      expect(output, contains('CONTENT1'));
-      expect(output, contains('CONTENT2'));
-    });
-  });
-}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
index 64731c3..26716a0 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
@@ -5,7 +5,7 @@
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:matcher/matcher.dart';
 
-import '../../../tool/lsp_spec/typescript_parser.dart';
+import '../../../tool/lsp_spec/meta_model.dart';
 
 Matcher isArrayOf(Matcher matcher) => ArrayTypeMatcher(wrapMatcher(matcher));
 
@@ -66,7 +66,7 @@
   bool matches(item, Map matchState) {
     return item is LiteralType &&
         _typeMatcher.matches(item.type, matchState) &&
-        item.literal == _value;
+        item.valueAsLiteral == _value;
   }
 }
 
@@ -100,7 +100,7 @@
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
-    if (item is Type) {
+    if (item is TypeReference) {
       return mismatchDescription
           .add('has the name ')
           .addDescriptionOf(item.name);
@@ -111,6 +111,6 @@
 
   @override
   bool matches(item, Map matchState) {
-    return item is Type && item.name == _expectedName;
+    return item is TypeReference && item.name == _expectedName;
   }
 }
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
new file mode 100644
index 0000000..b40c5aa
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/meta_model_test.dart
@@ -0,0 +1,548 @@
+// Copyright (c) 2018, 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 'package:test/test.dart';
+
+import '../../../tool/lsp_spec/meta_model.dart';
+import 'matchers.dart';
+
+void main() {
+  group('meta model reader', () {
+    test('reads an interface', () {
+      final input = {
+        "structures": [
+          {
+            "name": "SomeOptions",
+            "properties": [
+              {
+                "name": "options",
+                "type": {
+                  "kind": "array",
+                  "element": {"kind": "reference", "name": "string"}
+                },
+                "optional": true,
+                "documentation": "Options used by something.",
+              }
+            ],
+            "documentation": "Some options."
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.name, equals('SomeOptions'));
+      expect(interface.comment, equals('Some options.'));
+      expect(interface.baseTypes, hasLength(0));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      final field = interface.members[0] as Field;
+      expect(field.name, equals('options'));
+      expect(field.comment, equals('''Options used by something.'''));
+      expect(field.allowsNull, isFalse);
+      expect(field.allowsUndefined, isTrue);
+      expect(field.type, isArrayOf(isSimpleType('string')));
+    });
+
+    test('reads an interface with a field with an inline/unnamed type', () {
+      final input = {
+        "structures": [
+          {
+            "name": "Capabilities",
+            "properties": [
+              {
+                "name": "textDoc",
+                "type": {
+                  "kind": "literal",
+                  "value": {
+                    "properties": [
+                      {
+                        "name": "deprecated",
+                        "type": {"kind": "base", "name": "bool"},
+                        "optional": true,
+                      }
+                    ]
+                  }
+                },
+                "optional": true,
+              }
+            ],
+            "documentation": "Some options."
+          },
+        ],
+      };
+      final output = readModel(input);
+      // Length is two because we'll fabricate the type of textDoc.
+      expect(output, hasLength(2));
+
+      // Check there was a full fabricarted interface for this type.
+      expect(output[0], const TypeMatcher<Interface>());
+      var interface = output[0] as Interface;
+      expect(interface.name, equals('CapabilitiesTextDoc'));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      var field = interface.members[0] as Field;
+      expect(field.name, equals('deprecated'));
+      expect(field.allowsNull, isFalse);
+      expect(field.allowsUndefined, isTrue);
+      expect(field.type, isSimpleType('bool'));
+      expect(field.allowsUndefined, isTrue);
+
+      expect(output[1], const TypeMatcher<Interface>());
+      interface = output[1] as Interface;
+      expect(interface.name, equals('Capabilities'));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      field = interface.members[0] as Field;
+      expect(field.name, equals('textDoc'));
+      expect(field.allowsNull, isFalse);
+      expect(field.type, isSimpleType('CapabilitiesTextDoc'));
+    });
+
+    test('reads an interface with multiple fields', () {
+      final input = {
+        "structures": [
+          {
+            "name": "SomeOptions",
+            "properties": [
+              {
+                "name": "options0",
+                "type": {"kind": "reference", "name": "LSPAny"},
+                "documentation": "Options0 used by something.",
+              },
+              {
+                "name": "options1",
+                "type": {"kind": "reference", "name": "LSPAny"},
+                "documentation": "Options1 used by something.",
+              }
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.members, hasLength(2));
+      for (var i in [0, 1]) {
+        expect(interface.members[i], const TypeMatcher<Field>());
+        final field = interface.members[i] as Field;
+        expect(field.name, equals('options$i'));
+        expect(field.comment, equals('''Options$i used by something.'''));
+      }
+    });
+
+    test('reads an interface with a map into a MapType', () {
+      final input = {
+        "structures": [
+          {
+            "name": "WorkspaceEdit",
+            "properties": [
+              {
+                "name": "changes",
+                "type": {
+                  "kind": "map",
+                  "key": {"kind": "base", "name": "string"},
+                  "value": {
+                    "kind": "array",
+                    "element": {"kind": "reference", "name": "TextEdit"}
+                  },
+                },
+              }
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.members, hasLength(1));
+      final field = interface.members.first as Field;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('changes'));
+      expect(field.type,
+          isMapOf(isSimpleType('string'), isArrayOf(isSimpleType('TextEdit'))));
+    });
+
+    test('flags nullable undefined values', () {
+      final input = {
+        "structures": [
+          {
+            "name": "A",
+            "properties": [
+              {
+                "name": "canBeBoth",
+                "type": {
+                  "kind": "or",
+                  "items": [
+                    {"kind": "base", "name": "string"},
+                    {"kind": "base", "name": "null"}
+                  ]
+                },
+                "optional": true,
+              },
+              {
+                "name": "canBeNeither",
+                "type": {"kind": "base", "name": "string"},
+              },
+              {
+                "name": "canBeNull",
+                "type": {
+                  "kind": "or",
+                  "items": [
+                    {"kind": "base", "name": "string"},
+                    {"kind": "base", "name": "null"}
+                  ]
+                },
+              },
+              {
+                "name": "canBeUndefined",
+                "type": {"kind": "base", "name": "string"},
+                "optional": true,
+              },
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      final interface = output[0] as Interface;
+      expect(interface.members, hasLength(4));
+      for (var m in interface.members) {
+        expect(m, const TypeMatcher<Field>());
+      }
+      final canBeBoth = interface.members[0] as Field,
+          canBeNeither = interface.members[1] as Field,
+          canBeNull = interface.members[2] as Field,
+          canBeUndefined = interface.members[3] as Field;
+      expect(canBeNeither.allowsNull, isFalse);
+      expect(canBeNeither.allowsUndefined, isFalse);
+      expect(canBeNull.allowsNull, isTrue);
+      expect(canBeNull.allowsUndefined, isFalse);
+      expect(canBeUndefined.allowsNull, isFalse);
+      expect(canBeUndefined.allowsUndefined, isTrue);
+      expect(canBeBoth.allowsNull, isTrue);
+      expect(canBeBoth.allowsUndefined, isTrue);
+    });
+
+    test('formats comments correctly', () {
+      final input = {
+        "structures": [
+          {
+            "name": "A",
+            "properties": [],
+            "documentation": r"""
+Describes the what this class in lots of words that wrap onto multiple lines that will need re-wrapping to format nicely when converted into Dart.
+
+Blank lines should remain in-tact, as should:
+  - Indented
+  - Things
+
+Some docs have:
+- List items that are not indented
+
+Sometimes after a blank line we'll have a note.
+
+*Note* that something.""",
+          },
+        ],
+      };
+      final output = readModel(input);
+      final interface = output[0] as Interface;
+      expect(interface.comment, equals('''
+Describes the what this class in lots of words that wrap onto multiple lines that will need re-wrapping to format nicely when converted into Dart.
+
+Blank lines should remain in-tact, as should:
+  - Indented
+  - Things
+
+Some docs have:
+- List items that are not indented
+
+Sometimes after a blank line we'll have a note.
+
+*Note* that something.'''));
+    });
+
+    test('reads a type alias', () {
+      final input = {
+        "typeAliases": [
+          {
+            "name": "DocumentSelector",
+            "type": {
+              "kind": "array",
+              "element": {"kind": "reference", "name": "DocumentFilter"}
+            },
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<TypeAlias>());
+      final typeAlias = output[0] as TypeAlias;
+      expect(typeAlias.name, equals('DocumentSelector'));
+      expect(typeAlias.baseType, isArrayOf(isSimpleType('DocumentFilter')));
+    });
+
+    test('reads a type alias that is a union of unnamed types', () {
+      final input = {
+        "typeAliases": [
+          {
+            "name": "NameOrLength",
+            "type": {
+              "kind": "or",
+              "items": [
+                {
+                  "kind": "literal",
+                  "value": {
+                    "properties": [
+                      {
+                        "name": "name",
+                        "type": {"kind": "base", "name": "string"}
+                      },
+                    ]
+                  },
+                },
+                {
+                  "kind": "literal",
+                  "value": {
+                    "properties": [
+                      {
+                        "name": "length",
+                        "type": {"kind": "base", "name": "number"}
+                      },
+                    ]
+                  },
+                },
+              ]
+            },
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(3));
+
+      // Results should be the two inline interfaces followed by the type alias.
+
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface1 = output[0] as Interface;
+      expect(interface1.name, equals('NameOrLength1'));
+      expect(interface1.members, hasLength(1));
+      expect(interface1.members[0].name, equals('name'));
+
+      expect(output[1], const TypeMatcher<Interface>());
+      final interface2 = output[1] as Interface;
+      expect(interface2.name, equals('NameOrLength2'));
+      expect(interface2.members, hasLength(1));
+      expect(interface2.members[0].name, equals('length'));
+
+      expect(output[2], const TypeMatcher<TypeAlias>());
+      final typeAlias = output[2] as TypeAlias;
+      expect(typeAlias.name, equals('NameOrLength'));
+      expect(typeAlias.baseType, const TypeMatcher<UnionType>());
+
+      // The type alias should be a union of the two types above.
+      final union = typeAlias.baseType as UnionType;
+      expect(union.types, hasLength(2));
+      expect(union.types[0], isSimpleType(interface1.name));
+      expect(union.types[1], isSimpleType(interface2.name));
+    });
+
+    test('reads a namespace of constants', () {
+      final input = {
+        "enumerations": [
+          {
+            "name": "ResourceOperationKind",
+            "type": {"kind": "base", "name": "string"},
+            "values": [
+              {
+                "name": "Create",
+                "value": "create",
+                "documentation": "Supports creating new files and folders.",
+              },
+              {
+                "name": "Delete",
+                "value": "delete",
+                "documentation":
+                    "Supports deleting existing files and folders.",
+              },
+              {
+                "name": "Rename",
+                "value": "rename",
+                "documentation":
+                    "Supports renaming existing files and folders.",
+              },
+            ],
+          },
+        ]
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+
+      expect(output[0], const TypeMatcher<LspEnum>());
+      final namespace = output[0] as LspEnum;
+      expect(namespace.members, hasLength(3));
+      for (var m in namespace.members) {
+        expect(m, const TypeMatcher<Constant>());
+      }
+      final create = namespace.members[0] as Constant,
+          delete = namespace.members[1] as Constant,
+          rename = namespace.members[2] as Constant;
+      expect(create.name, equals('Create'));
+      expect(create.type, isSimpleType('ResourceOperationKind'));
+      expect(
+          create.comment, equals('Supports creating new files and folders.'));
+      expect(rename.name, equals('Rename'));
+      expect(rename.type, isSimpleType('ResourceOperationKind'));
+      expect(rename.comment,
+          equals('Supports renaming existing files and folders.'));
+      expect(delete.name, equals('Delete'));
+      expect(delete.type, isSimpleType('ResourceOperationKind'));
+      expect(delete.comment,
+          equals('Supports deleting existing files and folders.'));
+    });
+
+    test('reads a tuple in an array', () {
+      final input = {
+        "structures": [
+          {
+            "name": "SomeInformation",
+            "properties": [
+              {
+                "name": "label",
+                "type": {
+                  "kind": "or",
+                  "items": [
+                    {"kind": "base", "name": "string"},
+                    {
+                      "kind": "tuple",
+                      "items": [
+                        {"kind": "base", "name": "number"},
+                        {"kind": "base", "name": "number"}
+                      ]
+                    }
+                  ]
+                },
+              },
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.members, hasLength(1));
+      final field = interface.members.first as Field;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('label'));
+      expect(field.type, const TypeMatcher<UnionType>());
+      final union = field.type as UnionType;
+      expect(union.types, hasLength(2));
+      expect(union.types[0], isArrayOf(isSimpleType('number')));
+      expect(union.types[1], isSimpleType('string'));
+    });
+
+    test('reads an union including LSPObject into a single type', () {
+      final input = {
+        "structures": [
+          {
+            "name": "SomeInformation",
+            "properties": [
+              {
+                "name": "label",
+                "type": {
+                  "kind": "or",
+                  "items": [
+                    {"kind": "base", "name": "string"},
+                    {"kind": "base", "name": "LSPObject"},
+                  ]
+                },
+              },
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.members, hasLength(1));
+      final field = interface.members.first as Field;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('label'));
+      expect(field.type, isSimpleType('LSPObject'));
+    });
+
+    test('reads literal string values', () {
+      final input = {
+        "structures": [
+          {
+            "name": "MyType",
+            "properties": [
+              {
+                "name": "kind",
+                "type": {"kind": "stringLiteral", "value": "one"},
+              },
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.name, equals('MyType'));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      final field = interface.members[0] as Field;
+      expect(field.name, equals('kind'));
+      expect(field.allowsNull, isFalse);
+      expect(field.allowsUndefined, isFalse);
+      expect(field.type, isLiteralOf(isSimpleType('string'), "'one'"));
+    });
+
+    test('reads literal union values', () {
+      final input = {
+        "structures": [
+          {
+            "name": "MyType",
+            "properties": [
+              {
+                "name": "kind",
+                "type": {
+                  "kind": "or",
+                  "items": [
+                    {"kind": "stringLiteral", "value": "one"},
+                    {"kind": "stringLiteral", "value": "two"},
+                  ]
+                },
+              },
+            ],
+          },
+        ],
+      };
+      final output = readModel(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final interface = output[0] as Interface;
+      expect(interface.name, equals('MyType'));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      final field = interface.members[0] as Field;
+      expect(field.name, equals('kind'));
+      expect(field.allowsNull, isFalse);
+      expect(field.allowsUndefined, isFalse);
+      expect(field.type, const TypeMatcher<LiteralUnionType>());
+      final union = field.type as LiteralUnionType;
+      expect(union.types, hasLength(2));
+      expect(union.types[0], isLiteralOf(isSimpleType('string'), "'one'"));
+      expect(union.types[1], isLiteralOf(isSimpleType('string'), "'two'"));
+    });
+  });
+}
+
+List<LspEntity> readModel(Map<String, dynamic> model) =>
+    LspMetaModelCleaner().cleanTypes(LspMetaModelReader().readMap(model).types);
diff --git a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
index 07a4247..62b595f 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
@@ -7,15 +7,13 @@
 import 'dart_test.dart' as dart_test;
 import 'generated_classes_test.dart' as generated_classes_test;
 import 'json_test.dart' as json_test;
-import 'markdown_test.dart' as markdown_test;
-import 'typescript_test.dart' as typescript_test;
+import 'meta_model_test.dart' as meta_model_test;
 
 void main() {
   defineReflectiveSuite(() {
     dart_test.main();
     generated_classes_test.main();
     json_test.main();
-    markdown_test.main();
-    typescript_test.main();
+    meta_model_test.main();
   }, name: 'lsp-tool');
 }
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
deleted file mode 100644
index 386260e..0000000
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ /dev/null
@@ -1,437 +0,0 @@
-// Copyright (c) 2018, 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 'package:test/test.dart';
-
-import '../../../tool/lsp_spec/typescript_parser.dart';
-import 'matchers.dart';
-
-void main() {
-  group('typescript parser', () {
-    test('parses an interface', () {
-      final input = '''
-/**
- * Some options.
- */
-export interface SomeOptions {
-	/**
-	 * Options used by something.
-	 */
-	options?: OptionKind[];
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.name, equals('SomeOptions'));
-      expect(interface.commentText, equals('Some options.'));
-      expect(interface.baseTypes, hasLength(0));
-      expect(interface.members, hasLength(1));
-      expect(interface.members[0], const TypeMatcher<Field>());
-      final field = interface.members[0] as Field;
-      expect(field.name, equals('options'));
-      expect(field.commentText, equals('''Options used by something.'''));
-      expect(field.allowsNull, isFalse);
-      expect(field.allowsUndefined, isTrue);
-      expect(field.type, isArrayOf(isSimpleType('OptionKind')));
-    });
-
-    test('parses an interface with a field with an inline/unnamed type', () {
-      final input = '''
-export interface Capabilities {
-	textDoc?: {
-    deprecated?: bool;
-  };
-}
-    ''';
-      final output = parseString(input);
-      // Length is two because we'll fabricate the type of textDoc.
-      expect(output, hasLength(2));
-
-      // Check there was a full fabricarted interface for this type.
-      expect(output[0], const TypeMatcher<Interface>());
-      var interface = output[0] as Interface;
-      expect(interface.name, equals('CapabilitiesTextDoc'));
-      expect(interface.members, hasLength(1));
-      expect(interface.members[0], const TypeMatcher<Field>());
-      var field = interface.members[0] as Field;
-      expect(field.name, equals('deprecated'));
-      expect(field.allowsNull, isFalse);
-      expect(field.allowsUndefined, isTrue);
-      expect(field.type, isSimpleType('bool'));
-      expect(field.allowsUndefined, isTrue);
-
-      expect(output[1], const TypeMatcher<Interface>());
-      interface = output[1] as Interface;
-      expect(interface.name, equals('Capabilities'));
-      expect(interface.members, hasLength(1));
-      expect(interface.members[0], const TypeMatcher<Field>());
-      field = interface.members[0] as Field;
-      expect(field.name, equals('textDoc'));
-      expect(field.allowsNull, isFalse);
-      expect(field.type, isSimpleType('CapabilitiesTextDoc'));
-    });
-
-    test('parses an interface with multiple fields', () {
-      final input = '''
-export interface SomeOptions {
-	/**
-	 * Options0 used by something.
-	 */
-	options0: any;
-	/**
-	 * Options1 used by something.
-	 */
-	options1: any;
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(2));
-      for (var i in [0, 1]) {
-        expect(interface.members[i], const TypeMatcher<Field>());
-        final field = interface.members[i] as Field;
-        expect(field.name, equals('options$i'));
-        expect(field.commentText, equals('''Options$i used by something.'''));
-      }
-    });
-
-    test('parses an interface with type args', () {
-      final input = '''
-interface MyInterface<D> {
-	data?: D;
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(1));
-      final field = interface.members.first as Field;
-      expect(field, const TypeMatcher<Field>());
-      expect(field.name, equals('data'));
-      expect(field.allowsUndefined, isTrue);
-      expect(field.allowsNull, isFalse);
-      expect(field.type, isSimpleType('D'));
-    });
-
-    test('parses an interface with Arrays in Array<T> format', () {
-      final input = '''
-export interface MyMessage {
-	/**
-	 * The method's params.
-	 */
-	params?: Array<any> | string;
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(1));
-      final field = interface.members.first as Field;
-      expect(field, const TypeMatcher<Field>());
-      expect(field.name, equals('params'));
-      expect(field.commentText, equals('''The method's params.'''));
-      expect(field.allowsUndefined, isTrue);
-      expect(field.allowsNull, isFalse);
-      expect(field.type, const TypeMatcher<UnionType>());
-      final union = field.type as UnionType;
-      expect(union.types, hasLength(2));
-      expect(union.types[0], isArrayOf(isSimpleType('any')));
-      expect(union.types[1], isSimpleType('string'));
-    });
-
-    test('parses an interface with a map into a MapType', () {
-      final input = '''
-export interface WorkspaceEdit {
-	changes: { [uri: string]: TextEdit[]; };
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(1));
-      final field = interface.members.first as Field;
-      expect(field, const TypeMatcher<Field>());
-      expect(field.name, equals('changes'));
-      expect(field.type,
-          isMapOf(isSimpleType('string'), isArrayOf(isSimpleType('TextEdit'))));
-    });
-
-    test('flags nullable undefined values', () {
-      final input = '''
-export interface A {
-  canBeBoth?: string | null;
-  canBeNeither: string;
-	canBeNull: string | null;
-  canBeUndefined?: string;
-}
-    ''';
-      final output = parseString(input);
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(4));
-      for (var m in interface.members) {
-        expect(m, const TypeMatcher<Field>());
-      }
-      final canBeBoth = interface.members[0] as Field,
-          canBeNeither = interface.members[1] as Field,
-          canBeNull = interface.members[2] as Field,
-          canBeUndefined = interface.members[3] as Field;
-      expect(canBeNeither.allowsNull, isFalse);
-      expect(canBeNeither.allowsUndefined, isFalse);
-      expect(canBeNull.allowsNull, isTrue);
-      expect(canBeNull.allowsUndefined, isFalse);
-      expect(canBeUndefined.allowsNull, isFalse);
-      expect(canBeUndefined.allowsUndefined, isTrue);
-      expect(canBeBoth.allowsNull, isTrue);
-      expect(canBeBoth.allowsUndefined, isTrue);
-    });
-
-    test('formats comments correctly', () {
-      final input = '''
-/**
- * Describes the what this class in lots of words that wrap onto
- * multiple lines that will need re-wrapping to format nicely when
- * converted into Dart.
- *
- * Blank lines should remain in-tact, as should:
- *   - Indented
- *   - Things
- *
- * Some docs have:
- * - List items that are not indented
- *
- * Sometimes after a blank line we'll have a note.
- *
- * *Note* that something.
- */
-export interface A {
-  a: a;
-}
-    ''';
-      final output = parseString(input);
-      final interface = output[0] as Interface;
-      expect(interface.commentText, equals('''
-Describes the what this class in lots of words that wrap onto multiple lines that will need re-wrapping to format nicely when converted into Dart.
-
-Blank lines should remain in-tact, as should:
-  - Indented
-  - Things
-
-Some docs have:
-- List items that are not indented
-
-Sometimes after a blank line we'll have a note.
-
-*Note* that something.'''));
-    });
-
-    test('parses a type alias', () {
-      final input = '''
-export type DocumentSelector = DocumentFilter[];
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<TypeAlias>());
-      final typeAlias = output[0] as TypeAlias;
-      expect(typeAlias.name, equals('DocumentSelector'));
-      expect(typeAlias.baseType, isArrayOf(isSimpleType('DocumentFilter')));
-    });
-
-    test('parses a type alias that is a union of unnamed types', () {
-      final input = '''
-export type NameOrLength = { name: string } | { length: number };
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(3));
-
-      // Results should be the two inline interfaces followed by the type alias.
-
-      expect(output[0], const TypeMatcher<InlineInterface>());
-      final interface1 = output[0] as InlineInterface;
-      expect(interface1.name, equals('NameOrLength1'));
-      expect(interface1.members, hasLength(1));
-      expect(interface1.members[0].name, equals('name'));
-
-      expect(output[1], const TypeMatcher<InlineInterface>());
-      final interface2 = output[1] as InlineInterface;
-      expect(interface2.name, equals('NameOrLength2'));
-      expect(interface2.members, hasLength(1));
-      expect(interface2.members[0].name, equals('length'));
-
-      expect(output[2], const TypeMatcher<TypeAlias>());
-      final typeAlias = output[2] as TypeAlias;
-      expect(typeAlias.name, equals('NameOrLength'));
-      expect(typeAlias.baseType, const TypeMatcher<UnionType>());
-
-      // The type alias should be a union of the two types above.
-      final union = typeAlias.baseType as UnionType;
-      expect(union.types, hasLength(2));
-      expect(union.types[0], isSimpleType(interface1.name));
-      expect(union.types[1], isSimpleType(interface2.name));
-    });
-
-    test('parses a namespace of constants', () {
-      final input = '''
-export namespace ResourceOperationKind {
-	/**
-	 * Supports creating new files and folders.
-	 */
-	export const Create: ResourceOperationKind = 'create';
-
-	/**
-	 * Supports deleting existing files and folders.
-	 */
-	export const Delete: ResourceOperationKind = 'delete';
-
-	/**
-	 * Supports renaming existing files and folders.
-	 */
-	export const Rename: ResourceOperationKind = 'rename';
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Namespace>());
-      final namespace = output[0] as Namespace;
-      expect(namespace.members, hasLength(3));
-      for (var m in namespace.members) {
-        expect(m, const TypeMatcher<Const>());
-      }
-      final create = namespace.members[0] as Const,
-          delete = namespace.members[1] as Const,
-          rename = namespace.members[2] as Const;
-      expect(create.name, equals('Create'));
-      expect(create.type, isSimpleType('ResourceOperationKind'));
-      expect(create.commentText,
-          equals('Supports creating new files and folders.'));
-      expect(rename.name, equals('Rename'));
-      expect(rename.type, isSimpleType('ResourceOperationKind'));
-      expect(rename.commentText,
-          equals('Supports renaming existing files and folders.'));
-      expect(delete.name, equals('Delete'));
-      expect(delete.type, isSimpleType('ResourceOperationKind'));
-      expect(delete.commentText,
-          equals('Supports deleting existing files and folders.'));
-    });
-
-    test('parses an enum using keywords as identifiers', () {
-      final input = '''
-enum Foo {
-  namespace = 'namespace',
-  class = 'class',
-  enum = 'enum',
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output.first, const TypeMatcher<Namespace>());
-      final enum_ = output.first as Namespace;
-      expect(enum_.members, hasLength(3));
-      expect(enum_.members[0].name, equals('class'));
-      expect(enum_.members[1].name, equals('enum'));
-      expect(enum_.members[2].name, equals('namespace'));
-    });
-
-    test('parses a tuple in an array', () {
-      final input = '''
-interface SomeInformation {
-	label: string | [number, number];
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(1));
-      final field = interface.members.first as Field;
-      expect(field, const TypeMatcher<Field>());
-      expect(field.name, equals('label'));
-      expect(field.type, const TypeMatcher<UnionType>());
-      final union = field.type as UnionType;
-      expect(union.types, hasLength(2));
-      expect(union.types[0], isArrayOf(isSimpleType('number')));
-      expect(union.types[1], isSimpleType('string'));
-    });
-
-    test('parses an union including Object into a single type', () {
-      final input = '''
-interface SomeInformation {
-	label: string | object;
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.members, hasLength(1));
-      final field = interface.members.first as Field;
-      expect(field, const TypeMatcher<Field>());
-      expect(field.name, equals('label'));
-      expect(field.type, isSimpleType('object'));
-    });
-
-    test('parses multiple single-line comments into a single token', () {
-      final input = '''
-// This is line 1
-// This is line 2
-interface SomeInformation {
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0].commentNode!.token.lexeme, equals('''// This is line 1
-// This is line 2'''));
-    });
-
-    test('parses literal string values', () {
-      final input = '''
-export interface MyType {
-	kind: 'one';
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.name, equals('MyType'));
-      expect(interface.members, hasLength(1));
-      expect(interface.members[0], const TypeMatcher<Field>());
-      final field = interface.members[0] as Field;
-      expect(field.name, equals('kind'));
-      expect(field.allowsNull, isFalse);
-      expect(field.allowsUndefined, isFalse);
-      expect(field.type, isLiteralOf(isSimpleType('string'), "'one'"));
-    });
-
-    test('parses literal union values', () {
-      final input = '''
-export interface MyType {
-	kind: 'one' | 'two';
-}
-    ''';
-      final output = parseString(input);
-      expect(output, hasLength(1));
-      expect(output[0], const TypeMatcher<Interface>());
-      final interface = output[0] as Interface;
-      expect(interface.name, equals('MyType'));
-      expect(interface.members, hasLength(1));
-      expect(interface.members[0], const TypeMatcher<Field>());
-      final field = interface.members[0] as Field;
-      expect(field.name, equals('kind'));
-      expect(field.allowsNull, isFalse);
-      expect(field.allowsUndefined, isFalse);
-      expect(field.type, const TypeMatcher<LiteralUnionType>());
-      final union = field.type as LiteralUnionType;
-      expect(union.types, hasLength(2));
-      expect(union.types[0], isLiteralOf(isSimpleType('string'), "'one'"));
-      expect(union.types[1], isLiteralOf(isSimpleType('string'), "'two'"));
-    });
-  });
-}
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 2fe1e2e..2c1186e 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -5,13 +5,12 @@
 import 'package:collection/collection.dart';
 import 'package:dart_style/dart_style.dart';
 
-import 'typescript_parser.dart';
+import 'meta_model.dart';
 
 final formatter = DartFormatter();
 Map<String, Interface> _interfaces = {};
 
-/// TODO(dantup): Rename namespaces -> enums since they're always that now.
-Map<String, Namespace> _namespaces = {};
+Map<String, LspEnum> _namespaces = {};
 Map<String, List<String>> _subtypes = {};
 Map<String, TypeAlias> _typeAliases = {};
 
@@ -35,7 +34,7 @@
       name != 'ResourceOperationKind';
 }
 
-String generateDartForTypes(List<AstNode> types) {
+String generateDartForTypes(List<LspEntity> types) {
   final buffer = IndentableStringBuffer();
   _getSortedUnique(types).forEach((t) => _writeType(buffer, t));
   final stopwatch = Stopwatch()..start();
@@ -47,7 +46,7 @@
   return '${formattedCode.trim()}\n'; // Ensure a single trailing newline.
 }
 
-void recordTypes(List<AstNode> types) {
+void recordTypes(List<LspEntity> types) {
   types
       .whereType<TypeAlias>()
       .forEach((alias) => _typeAliases[alias.name] = alias);
@@ -61,67 +60,21 @@
     }
   });
   types
-      .whereType<Namespace>()
+      .whereType<LspEnum>()
       .forEach((namespace) => _namespaces[namespace.name] = namespace);
   _sortSubtypes();
 }
 
-/// Renames types that may have been generated with bad names.
-Iterable<AstNode> renameTypes(List<AstNode> types) sync* {
-  const renames = {
-    // TODO(dantup): These entries can be removed after the
-    //   the migration to JSON meta_model.
-    'ClientCapabilitiesWindow': 'WindowClientCapabilities',
-    'ClientCapabilitiesWorkspace': 'WorkspaceClientCapabilities',
-    'ClientCapabilitiesWorkspaceFileOperations':
-        'FileOperationClientCapabilities',
-    'ServerCapabilitiesWorkspaceFileOperations': 'FileOperationOptions',
-    'ClientCapabilitiesGeneral': 'GeneralClientCapabilities',
-    'CompletionClientCapabilitiesCompletionItemInsertTextModeSupport':
-        'CompletionItemInsertTextModeSupport',
-    'CompletionClientCapabilitiesCompletionItemResolveSupport':
-        'CompletionItemResolveSupport',
-    'CompletionClientCapabilitiesCompletionItemTagSupport':
-        'CompletionItemTagSupport',
-    'CodeActionClientCapabilitiesCodeActionLiteralSupportCodeActionKind':
-        'CodeActionLiteralSupportCodeActionKind',
-    // In JSON model this becomes a union of literals which we assign improved
-    // names to (to avoid numeric suffixes).
-    'DocumentFilter': 'TextDocumentFilterWithScheme',
-    'ClientCapabilitiesGeneralStaleRequestSupport':
-        'GeneralClientCapabilitiesStaleRequestSupport',
-    'SignatureHelpClientCapabilitiesSignatureInformationParameterInformation':
-        'SignatureInformationParameterInformation',
-    'CompletionListItemDefaultsEditRange': 'CompletionItemEditRange',
-  };
-
-  for (final type in types) {
-    if (type is Interface) {
-      final newName = renames[type.name];
-      if (newName != null) {
-        // Replace with renamed interface.
-        yield Interface(
-          type.commentNode,
-          Token.identifier(newName),
-          type.typeArgs,
-          type.baseTypes,
-          type.members,
-        );
-        // Plus a TypeAlias for the old name.
-        yield TypeAlias(
-          type.commentNode,
-          Token.identifier(type.name),
-          Type.identifier(newName),
-        );
-        continue;
+TypeBase resolveTypeAlias(TypeBase type, {bool resolveEnumClasses = false}) {
+  if (type is TypeReference) {
+    if (resolveEnumClasses) {
+      // 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];
+      if (enum_ != null) {
+        return enum_.typeOfValues;
       }
     }
-    yield type;
-  }
-}
-
-TypeBase resolveTypeAlias(TypeBase type, {bool resolveEnumClasses = false}) {
-  if (type is Type) {
     // 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`
@@ -165,27 +118,31 @@
   return code;
 }
 
-/// Recursively gets all members from superclasses.
-List<Field> _getAllFields(Interface? interface) {
+/// Recursively gets all members from superclasses and returns them sorted
+/// alphabetically.
+List<Field> _getAllFields(Interface? interface) =>
+    _getSortedUnique(_getAllFieldsMap(interface).values.toList());
+
+/// Recursively gets all members from superclasses keyed by field name.
+Map<String, Field> _getAllFieldsMap(Interface? interface) {
   // Handle missing interfaces (such as special cased interfaces that won't
   // be included in this model).
   if (interface == null) {
-    return [];
+    return {};
   }
 
-  final allFields = interface.members
-      .whereType<Field>()
-      .followedBy(interface.baseTypes
-          // This cast is safe because base types are always real types.
-          .map((type) => _getAllFields(_interfaces[(type as Type).name]))
-          .expand((ts) => ts))
-      .toList();
-
-  return _getSortedUnique(allFields);
+  // It's possible our interface redefines something in a base type (for example
+  // where the base has `String` but this type overrides it with a literal such
+  // as `ResourceOperation`) so use a map to keep the most-specific by name.
+  return {
+    for (final baseType in interface.baseTypes)
+      ..._getAllFieldsMap(_interfaces[baseType.name]),
+    for (final field in interface.members.whereType<Field>()) field.name: field,
+  };
 }
 
 /// Returns a copy of the list sorted by name with duplicates (by name+type) removed.
-List<N> _getSortedUnique<N extends AstNode>(List<N> items) {
+List<N> _getSortedUnique<N extends LspEntity>(List<N> items) {
   final uniqueByName = <String, N>{};
   for (var item in items) {
     // It's fine to have the same name used for different types (eg. namespace +
@@ -213,9 +170,9 @@
   type = resolveTypeAlias(type);
 
   if (type is LiteralType) {
-    return 'must be the literal ${type.literal}';
+    return 'must be the literal ${type.valueAsLiteral}';
   } else if (type is LiteralUnionType) {
-    return 'must be one of the literals ${type.literalTypes.map((t) => t.literal).join(', ')}';
+    return 'must be one of the literals ${type.literalTypes.map((t) => t.valueAsLiteral).join(', ')}';
   } else {
     return 'must be of type ${type.dartTypeWithTypeArgs}';
   }
@@ -223,7 +180,7 @@
 
 bool _isOverride(Interface interface, Field field) {
   for (var parentType in interface.baseTypes) {
-    var parent = _interfaces[(parentType as Type).name];
+    var parent = _interfaces[parentType.name];
     if (parent != null) {
       if (parent.members.any((m) => m.name == field.name)) {
         return true;
@@ -238,12 +195,13 @@
 
 bool _isSimpleType(TypeBase type) {
   const literals = ['num', 'String', 'bool', 'int'];
-  return type is Type && literals.contains(type.dartType);
+  return type is TypeReference && literals.contains(type.dartType);
 }
 
 bool _isSpecType(TypeBase type) {
   type = resolveTypeAlias(type);
-  return type is Type &&
+  return type is TypeReference &&
+      !isAnyType(type) &&
       (_interfaces.containsKey(type.name) ||
           (_namespaces.containsKey(type.name)));
 }
@@ -257,6 +215,7 @@
     'String': 'Str',
     'class': 'class_',
     'enum': 'enum_',
+    'null': 'null_',
   };
   return map[identifier] ?? identifier;
 }
@@ -311,8 +270,8 @@
 /// This is `Map<String, Object?>` for complex types but can be a simple type
 /// for enums.
 String _specJsonType(TypeBase type) {
-  if (type is Type && _namespaces.containsKey(type.name)) {
-    final valueType = _namespaces[type.name]!.members.cast<Const>().first.type;
+  if (type is TypeReference && _namespaces.containsKey(type.name)) {
+    final valueType = _namespaces[type.name]!.typeOfValues;
     return resolveTypeAlias(valueType, resolveEnumClasses: true)
         .dartTypeWithTypeArgs;
   }
@@ -418,7 +377,7 @@
     ..writeIndentedln('}');
 }
 
-void _writeConst(IndentableStringBuffer buffer, Const cons) {
+void _writeConst(IndentableStringBuffer buffer, Constant cons) {
   _writeDocCommentsAndAnnotations(buffer, cons);
   buffer.writeIndentedln('static const ${cons.name} = ${cons.valueAsLiteral};');
 }
@@ -432,11 +391,13 @@
     ..writeIndented('${interface.name}({')
     ..write(allFields.map((field) {
       final isLiteral = field.type is LiteralType;
-      final isRequired =
-          !isLiteral && !field.allowsNull && !field.allowsUndefined;
+      final isRequired = !isLiteral &&
+          !field.allowsNull &&
+          !field.allowsUndefined &&
+          !isAnyType(field.type);
       final requiredKeyword = isRequired ? 'required' : '';
       final valueCode =
-          isLiteral ? ' = ${(field.type as LiteralType).literal}' : '';
+          isLiteral ? ' = ${(field.type as LiteralType).valueAsLiteral}' : '';
       return '$requiredKeyword this.${field.name}$valueCode, ';
     }).join())
     ..write('})');
@@ -450,10 +411,10 @@
       final type = field.type;
       if (type is LiteralType) {
         buffer
-          ..writeIndentedln('if (${field.name} != ${type.literal}) {')
+          ..writeIndentedln('if (${field.name} != ${type.valueAsLiteral}) {')
           ..indent()
           ..writeIndentedln(
-              "throw '${field.name} may only be the literal ${type.literal.replaceAll("'", "\\'")}';")
+              "throw '${field.name} may only be the literal ${type.valueAsLiteral.replaceAll("'", "\\'")}';")
           ..outdent()
           ..writeIndentedln('}');
       }
@@ -467,8 +428,8 @@
 }
 
 void _writeDocCommentsAndAnnotations(
-    IndentableStringBuffer buffer, AstNode node) {
-  var comment = node.commentText?.trim();
+    IndentableStringBuffer buffer, LspEntity node) {
+  var comment = node.comment?.trim();
   if (comment != null && comment.isNotEmpty) {
     comment = _rewriteCommentReference(comment);
     var originalLines = comment.split('\n');
@@ -489,19 +450,13 @@
   // }
 }
 
-void _writeEnumClass(IndentableStringBuffer buffer, Namespace namespace) {
+void _writeEnumClass(IndentableStringBuffer buffer, LspEnum namespace) {
   _writeDocCommentsAndAnnotations(buffer, namespace);
-  final consts = namespace.members.cast<Const>().toList();
-  final allowsAnyValue = enumClassAllowsAnyValue(namespace.name);
-  final constructorName = allowsAnyValue ? '' : '._';
-  final firstValueType = consts.first.type;
-  // Enums can have constant values in their fields so if a field is a literal
-  // use its underlying type for type checking.
-  final requiredValueType =
-      firstValueType is LiteralType ? firstValueType.type : firstValueType;
-  final typeOfValues =
-      resolveTypeAlias(requiredValueType, resolveEnumClasses: true);
+  final consts = namespace.members.cast<Constant>().toList();
   final namespaceName = namespace.name;
+  final typeOfValues = namespace.typeOfValues;
+  final allowsAnyValue = enumClassAllowsAnyValue(namespaceName);
+  final constructorName = allowsAnyValue ? '' : '._';
 
   buffer
     ..writeln('class $namespaceName implements ToJsonable {')
@@ -536,14 +491,16 @@
   buffer
     ..outdent()
     ..writeIndentedln('}');
-  namespace.members.whereType<Const>().forEach((cons) {
+  namespace.members.whereType<Constant>().forEach((cons) {
     // We don't use any deprecated enum values, so omit them entirely.
     if (cons.isDeprecated) {
       return;
     }
     _writeDocCommentsAndAnnotations(buffer, cons);
+    final memberName = _makeValidIdentifier(cons.name);
+    final value = cons.valueAsLiteral;
     buffer.writeIndentedln(
-        'static const ${_makeValidIdentifier(cons.name)} = $namespaceName$constructorName(${cons.valueAsLiteral});');
+        'static const $memberName = $namespaceName$constructorName($value);');
   });
   buffer
     ..writeln()
@@ -683,7 +640,7 @@
     {required bool allowsNull}) {
   final allowedValues = [
     if (allowsNull) null,
-    ...union.literalTypes.map((t) => t.literal)
+    ...union.literalTypes.map((t) => t.valueAsLiteral)
   ];
   final valueType = union.literalTypes.first.dartTypeWithTypeArgs;
   final cast = ' as $valueType${allowsNull ? '?' : ''}';
@@ -769,7 +726,7 @@
     // Add a local variable to allow type promotion (and avoid multiple lookups).
     final localName = _makeValidIdentifier(field.name);
     final localNameJson = '${localName}Json';
-    buffer.writeIndented("final $localNameJson = json['${field.name}'];");
+    buffer.writeIndentedln("final $localNameJson = json['${field.name}'];");
     buffer.writeIndented('final $localName = ');
     _writeFromJsonCode(buffer, field.type, localNameJson,
         allowsNull: field.allowsNull || field.allowsUndefined);
@@ -824,6 +781,7 @@
 }
 
 void _writeInterface(IndentableStringBuffer buffer, Interface interface) {
+  final isPrivate = interface.name.startsWith('_');
   _writeDocCommentsAndAnnotations(buffer, interface);
 
   buffer.writeIndented('class ${interface.nameWithTypeArgs} ');
@@ -836,12 +794,14 @@
   buffer
     ..writeln('{')
     ..indent();
-  _writeJsonHandler(buffer, interface);
+  if (!isPrivate) {
+    _writeJsonHandler(buffer, interface);
+  }
   _writeConstructor(buffer, interface);
   _writeFromJsonConstructor(buffer, interface);
   // Handle Consts and Fields separately, since we need to include superclass
   // Fields.
-  final consts = interface.members.whereType<Const>().toList();
+  final consts = interface.members.whereType<Constant>().toList();
   final fields = _getAllFields(interface);
   buffer.writeln();
   _writeMembers(buffer, interface, consts);
@@ -893,7 +853,7 @@
     IndentableStringBuffer buffer, Interface interface, Member member) {
   if (member is Field) {
     _writeField(buffer, interface, member);
-  } else if (member is Const) {
+  } else if (member is Constant) {
     _writeConst(buffer, member);
   } else {
     throw 'Unknown type';
@@ -986,10 +946,10 @@
     ..writeIndentedln('String toString() => jsonEncoder.convert(toJson());');
 }
 
-void _writeType(IndentableStringBuffer buffer, AstNode type) {
+void _writeType(IndentableStringBuffer buffer, LspEntity type) {
   if (type is Interface) {
     _writeInterface(buffer, type);
-  } else if (type is Namespace) {
+  } 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
@@ -1019,7 +979,7 @@
     buffer.write('$valueCode is$operator $fullDartType');
   } else if (type is LiteralType) {
     final equals = negation ? '!=' : '==';
-    buffer.write('$valueCode $equals ${type.literal}');
+    buffer.write('$valueCode $equals ${type.valueAsLiteral}');
   } else if (_isSpecType(type)) {
     buffer.write('$operator$dartType.canParse($valueCode, $reporter)');
   } else if (type is ArrayType) {
@@ -1028,8 +988,6 @@
     }
     buffer.write('$valueCode is$operator List<Object?>');
     if (fullDartType != 'Object?') {
-      // TODO(dantup): If we're happy to assume we never have two lists in a union
-      // we could skip this bit.
       buffer.write(' $and $valueCode.$every((item) => ');
       _writeTypeCheckCondition(
           buffer, interface, 'item', type.elementType, reporter,
@@ -1078,7 +1036,7 @@
       buffer.write(')');
     }
   } else if (interface != null &&
-      interface.typeArgs.any((typeArg) => typeArg.lexeme == fullDartType)) {
+      interface.typeArgs.any((typeArg) => typeArg == fullDartType)) {
     final comment = '/* $operator$fullDartType.canParse($valueCode) */';
     print(
         'WARN: Unable to write a type check for $valueCode with generic type $fullDartType. '
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index d22b884..d9aca9a 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -4,15 +4,12 @@
 
 import 'dart:io';
 
-import 'package:analysis_server/src/utilities/strings.dart';
 import 'package:args/args.dart';
 import 'package:http/http.dart' as http;
 import 'package:path/path.dart' as path;
 
 import 'codegen_dart.dart';
-import 'markdown.dart';
-import 'typescript.dart';
-import 'typescript_parser.dart';
+import 'meta_model.dart';
 
 Future<void> main(List<String> arguments) async {
   final args = argParser.parse(arguments);
@@ -28,14 +25,9 @@
   final outFolder = path.join(packageFolder, 'lib', 'lsp_protocol');
   Directory(outFolder).createSync();
 
-  // Collect definitions for types in the spec and our custom extensions.
-  var specTypes = await getSpecClasses(args);
-  var customTypes = getCustomClasses();
-
-  // Handle some renames of types where we generate names that might not be
-  // ideal.
-  specTypes = renameTypes(specTypes).toList();
-  customTypes = renameTypes(customTypes).toList();
+  // Collect definitions for types in the model and our custom extensions.
+  final specTypes = await getSpecClasses(args);
+  final customTypes = getCustomClasses();
 
   // Record both sets of types in dictionaries for faster lookups, but also so
   // they can reference each other and we can find the definitions during
@@ -65,96 +57,35 @@
       help:
           'Download the latest version of the LSP spec before generating types');
 
+final String localLicensePath = path.join(
+    path.dirname(Platform.script.toFilePath()), 'lsp_meta_model.license.txt');
+
 final String localSpecPath = path.join(
-    path.dirname(Platform.script.toFilePath()), 'lsp_specification.md');
+    path.dirname(Platform.script.toFilePath()), 'lsp_meta_model.json');
 
 final Uri specLicenseUri = Uri.parse(
-    'https://raw.githubusercontent.com/Microsoft/language-server-protocol/gh-pages/License.txt');
+    'https://microsoft.github.io/language-server-protocol/License.txt');
 
-/// The URI of the version of the spec to generate from. This should be periodically updated as
-/// there's no longer a stable URI for the latest published version.
+/// The URI of the version of the LSP meta model to generate from. This should
+/// be periodically updated to the latest version.
 final Uri specUri = Uri.parse(
-    'https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/lsp/3.17/specification.md');
-
-/// Pattern to extract inline types from the `result: {xx, yy }` notes in the spec.
-/// Doesn't parse past full stops as some of these have english sentences tagged on
-/// the end that we don't want to parse.
-final _resultsInlineTypesPattern = RegExp(r'''\* result:[^\.{}]*({[^\.`]*})''');
+    'https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/metaModel/metaModel.json');
 
 Future<void> downloadSpec() async {
   final specResp = await http.get(specUri);
   final licenseResp = await http.get(specLicenseUri);
-  final text = [
-    '''
-This is an unmodified copy of the Language Server Protocol Specification,
-downloaded from $specUri. It is the version of the specification that was
-used to generate a portion of the Dart code used to support the protocol.
 
-To regenerate the generated code, run the script in
-"analysis_server/tool/lsp_spec/generate_all.dart" with no arguments. To
-download the latest version of the specification before regenerating the
-code, run the same script with an argument of "--download".''',
-    licenseResp.body,
-    await _fetchIncludes(specResp.body, specUri),
-  ];
-  await File(localSpecPath).writeAsString(text.join('\n\n---\n\n'));
-}
+  assert(specResp.statusCode == 200);
+  assert(licenseResp.statusCode == 200);
 
-Namespace extractMethodsEnum(String spec) {
-  Const toConstant(String value) {
-    final comment = Comment(
-        Token(TokenType.COMMENT, '''Constant for the '$value' method.'''));
-
-    // Generate a safe name for the member from the string. Those that start with
-    // $/ will have the prefix removed and all slashes should be replaced with
-    // underscores.
-    final safeMemberName = value.replaceAll(r'$/', '').replaceAll('/', '_');
-
-    return Const(
-      comment,
-      Token.identifier(safeMemberName),
-      Type.identifier('string'),
-      Token(TokenType.STRING, "'$value'"),
-    );
-  }
-
-  final comment = Comment(Token(TokenType.COMMENT,
-      'Valid LSP methods known at the time of code generation from the spec.'));
-  final methodConstants = extractMethodNames(spec).map(toConstant).toList();
-
-  return Namespace(comment, Token.identifier('Method'), methodConstants);
-}
-
-/// Extract inline types found directly in the `results:` sections of the spec
-/// that are not declared with their own names elsewhere.
-List<AstNode> extractResultsInlineTypes(String spec) {
-  InlineInterface toInterface(String typeDef) {
-    // The definition passed here will be a bare inline type, such as:
-    //
-    //     { range: Range, placeholder: string }
-    //
-    // In order to parse this, we'll just format it as a type alias and then
-    // run it through the standard parsing code.
-    final typeAlias = 'type temp = ${typeDef.replaceAll(',', ';')};';
-
-    final parsed = parseString(typeAlias);
-
-    // Extract the InlineInterface that was created.
-    final interface =
-        parsed.firstWhere((t) => t is InlineInterface) as InlineInterface;
-
-    // Create a new name based on the fields.
-    var newName = interface.members.map((m) => capitalize(m.name)).join('And');
-
-    return InlineInterface(newName, interface.members);
-  }
-
-  return _resultsInlineTypesPattern
-      .allMatches(spec)
-      .map((m) => m.group(1)!.trim())
-      .toList()
-      .map(toInterface)
-      .toList();
+  await File(localSpecPath).writeAsString(specResp.body);
+  await File(localLicensePath).writeAsString(
+    'This license is for the ${path.basename(localSpecPath)} file.\n\n'
+    '${path.basename(localLicensePath)} downloaded from: $specLicenseUri\n'
+    '${path.basename(localSpecPath)} downloaded from: $specUri\n'
+    '\n--\n\n'
+    '${licenseResp.body}',
+  );
 }
 
 String generatedFileHeader(int year, {bool importCustom = false}) => '''
@@ -178,17 +109,17 @@
 
 ''';
 
-List<AstNode> getCustomClasses() {
+List<LspEntity> getCustomClasses() {
+  /// Helper to create an interface type.
   Interface interface(String name, List<Member> fields, {String? baseType}) {
     return Interface(
-      null,
-      Token.identifier(name),
-      [],
-      [if (baseType != null) Type.identifier(baseType)],
-      fields,
+      name: name,
+      baseTypes: [if (baseType != null) TypeReference(baseType)],
+      members: fields,
     );
   }
 
+  /// Helper to create a field.
   Field field(
     String name, {
     String? comment,
@@ -197,29 +128,43 @@
     bool canBeUndefined = false,
   }) {
     final fieldType =
-        array ? ArrayType(Type.identifier(type)) : Type.identifier(type);
-    final commentNode =
-        comment != null ? Comment(Token(TokenType.COMMENT, comment)) : null;
+        array ? ArrayType(TypeReference(type)) : TypeReference(type);
 
     return Field(
-      commentNode,
-      Token.identifier(name),
-      fieldType,
+      name: name,
+      comment: comment,
+      type: fieldType,
       allowsNull: false,
       allowsUndefined: canBeUndefined,
     );
   }
 
-  final customTypes = <AstNode>[
+  final customTypes = <LspEntity>[
     TypeAlias(
-      null,
-      Token.identifier('LSPAny'),
-      Type.Any,
+      name: 'LSPAny',
+      baseType: TypeReference.Any,
     ),
     TypeAlias(
-      null,
-      Token.identifier('LSPObject'),
-      Type.Any,
+      name: 'LSPObject',
+      baseType: TypeReference.Any,
+    ),
+    // The DocumentFilter more complex in v3.17's meta_model (to allow
+    // TextDocumentFilters to be guaranteed to have at least one of language,
+    // pattern, scheme) but we only ever use a single type in the server so
+    // for compatibility, alias that type to the original TS-spec name.
+    // TODO(dantup): Improve this after the TS->JSON Spec migration.
+    TypeAlias(
+      name: 'DocumentFilter',
+      baseType: TypeReference('TextDocumentFilter2'),
+    ),
+    // Similarly, the meta_model includes String as an option for
+    // DocumentSelector which is deprecated and we never previously supported
+    // (because the TypeScript spec did not include it in the type) so preserve
+    // that.
+    // TODO(dantup): Improve this after the TS->JSON Spec migration.
+    TypeAlias(
+      name: 'DocumentSelector',
+      baseType: ArrayType(TypeReference('TextDocumentFilterWithScheme')),
     ),
     interface('Message', [
       field('jsonrpc', type: 'string'),
@@ -237,9 +182,8 @@
       'RequestMessage',
       [
         Field(
-          null,
-          Token.identifier('id'),
-          UnionType([Type.identifier('int'), Type.identifier('string')]),
+          name: 'id',
+          type: UnionType([TypeReference('int'), TypeReference('string')]),
           allowsNull: false,
           allowsUndefined: false,
         )
@@ -255,9 +199,8 @@
       'ResponseMessage',
       [
         Field(
-          null,
-          Token.identifier('id'),
-          UnionType([Type.identifier('int'), Type.identifier('string')]),
+          name: 'id',
+          type: UnionType([TypeReference('int'), TypeReference('string')]),
           allowsNull: true,
           allowsUndefined: false,
         ),
@@ -285,7 +228,10 @@
         ),
       ],
     ),
-    TypeAlias(null, Token.identifier('DocumentUri'), Type.identifier('string')),
+    TypeAlias(
+      name: 'DocumentUri',
+      baseType: TypeReference('string'),
+    ),
 
     interface('DartDiagnosticServer', [field('port', type: 'int')]),
     interface('AnalyzerStatusParams', [field('isAnalyzing', type: 'boolean')]),
@@ -381,13 +327,12 @@
       ],
     ),
     TypeAlias(
-      null,
-      Token.identifier('TextDocumentEditEdits'),
-      ArrayType(
+      name: 'TextDocumentEditEdits',
+      baseType: ArrayType(
         UnionType([
-          Type.identifier('SnippetTextEdit'),
-          Type.identifier('AnnotatedTextEdit'),
-          Type.identifier('TextEdit'),
+          TypeReference('SnippetTextEdit'),
+          TypeReference('AnnotatedTextEdit'),
+          TypeReference('TextEdit'),
         ]),
       ),
     )
@@ -395,84 +340,15 @@
   return customTypes;
 }
 
-Future<List<AstNode>> getSpecClasses(ArgResults args) async {
+Future<List<LspEntity>> getSpecClasses(ArgResults args) async {
   var download = args[argDownload] as bool;
   if (download) {
     await downloadSpec();
   }
-  final spec = await readSpec();
 
-  final types = extractTypeScriptBlocks(spec)
-      .where(shouldIncludeScriptBlock)
-      .map(parseString)
-      .expand((f) => f)
-      .where(includeTypeDefinitionInOutput)
-      .toList();
+  final file = File(localSpecPath);
+  var model = LspMetaModelReader().readFile(file);
+  model = LspMetaModelCleaner().cleanModel(model);
 
-  // Generate an enum for all of the request methods to avoid strings.
-  types.add(extractMethodsEnum(spec));
-
-  // Extract additional inline types that are specified online in the `results`
-  // section of the doc.
-  types.addAll(extractResultsInlineTypes(spec));
-  return types;
-}
-
-Future<String> readSpec() => File(localSpecPath).readAsString();
-
-/// Returns whether a script block should be parsed or not.
-bool shouldIncludeScriptBlock(String input) {
-  // Skip over some typescript blocks that are known sample code and not part
-  // of the LSP spec.
-  if (input.trim() == r"export const EOL: string[] = ['\n', '\r\n', '\r'];" ||
-      input.startsWith('textDocument.codeAction.resolveSupport =') ||
-      input.startsWith('textDocument.inlayHint.resolveSupport =') ||
-      // These two are example definitions, the real definitions start "export"
-      // and contain some base classes.
-      input.startsWith('interface HoverParams {') ||
-      input.startsWith('interface HoverResult {')) {
-    return false;
-  }
-
-  // There are some code blocks that just have example JSON in them.
-  if (input.startsWith('{') && input.endsWith('}')) {
-    return false;
-  }
-
-  // There are some example blocks that just contain arrays with no definitions.
-  // They're most easily noted by ending with `]` which no valid TypeScript blocks
-  // do.
-  if (input.trim().endsWith(']')) {
-    return false;
-  }
-
-  // There's a chunk of typescript that is just a partial snippet from a real
-  // interface declared elsewhere that we can only detect by the leading comment.
-  if (input
-      .replaceAll('\r', '')
-      .startsWith('/**\n\t * Window specific client capabilities.')) {
-    return false;
-  }
-
-  return true;
-}
-
-/// Fetches and in-lines any includes that appear in [spec] in the form
-/// `{% include_relative types/uri.md %}`.
-Future<String> _fetchIncludes(String spec, Uri baseUri) async {
-  final pattern = RegExp(r'{% include_relative ([\w\-.\/]+.md) %}');
-  final includeStrings = <String, String>{};
-  for (final match in pattern.allMatches(spec)) {
-    final relativeUri = match.group(1)!;
-    final fullUri = baseUri.resolve(relativeUri);
-    final response = await http.get(fullUri);
-    if (response.statusCode != 200) {
-      throw 'Failed to fetch $fullUri (${response.statusCode} ${response.reasonPhrase})';
-    }
-    includeStrings[relativeUri] = response.body;
-  }
-  return spec.replaceAllMapped(
-    pattern,
-    (match) => includeStrings[match.group(1)!]!,
-  );
+  return model.types;
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.json b/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.json
new file mode 100644
index 0000000..eb3205e
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.json
@@ -0,0 +1,14316 @@
+{
+	"requests": [
+		{
+			"method": "textDocument/implementation",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Definition"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ImplementationParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "ImplementationRegistrationOptions"
+			},
+			"documentation": "A request to resolve the implementation locations of a symbol at a given text\ndocument position. The request's parameter is of type [TextDocumentPositionParams]\n(#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a\nThenable that resolves to such."
+		},
+		{
+			"method": "textDocument/typeDefinition",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Definition"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "TypeDefinitionParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TypeDefinitionRegistrationOptions"
+			},
+			"documentation": "A request to resolve the type definition locations of a symbol at a given text\ndocument position. The request's parameter is of type [TextDocumentPositioParams]\n(#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a\nThenable that resolves to such."
+		},
+		{
+			"method": "workspace/workspaceFolders",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceFolder"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"documentation": "The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders."
+		},
+		{
+			"method": "workspace/configuration",
+			"result": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "LSPAny"
+				}
+			},
+			"params": {
+				"kind": "and",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "ConfigurationParams"
+					},
+					{
+						"kind": "reference",
+						"name": "PartialResultParams"
+					}
+				]
+			},
+			"documentation": "The 'workspace/configuration' request is sent from the server to the client to fetch a certain\nconfiguration setting.\n\nThis pull model replaces the old push model were the client signaled configuration change via an\nevent. If the server still needs to react to configuration changes (since the server caches the\nresult of `workspace/configuration` requests) the server should register for an empty configuration\nchange event and empty the cache if such an event is received."
+		},
+		{
+			"method": "textDocument/documentColor",
+			"result": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "ColorInformation"
+				}
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentColorParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "ColorInformation"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentColorRegistrationOptions"
+			},
+			"documentation": "A request to list all color symbols found in a given text document. The request's\nparameter is of type [DocumentColorParams](#DocumentColorParams) the\nresponse is of type [ColorInformation[]](#ColorInformation) or a Thenable\nthat resolves to such."
+		},
+		{
+			"method": "textDocument/colorPresentation",
+			"result": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "ColorPresentation"
+				}
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ColorPresentationParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "ColorPresentation"
+				}
+			},
+			"registrationOptions": {
+				"kind": "and",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkDoneProgressOptions"
+					},
+					{
+						"kind": "reference",
+						"name": "TextDocumentRegistrationOptions"
+					}
+				]
+			},
+			"documentation": "A request to list all presentation for a color. The request's\nparameter is of type [ColorPresentationParams](#ColorPresentationParams) the\nresponse is of type [ColorInformation[]](#ColorInformation) or a Thenable\nthat resolves to such."
+		},
+		{
+			"method": "textDocument/foldingRange",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FoldingRange"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "FoldingRangeParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "FoldingRange"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FoldingRangeRegistrationOptions"
+			},
+			"documentation": "A request to provide folding ranges in a document. The request's\nparameter is of type [FoldingRangeParams](#FoldingRangeParams), the\nresponse is of type [FoldingRangeList](#FoldingRangeList) or a Thenable\nthat resolves to such."
+		},
+		{
+			"method": "textDocument/declaration",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Declaration"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DeclarationLink"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DeclarationParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DeclarationLink"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DeclarationRegistrationOptions"
+			},
+			"documentation": "A request to resolve the type definition locations of a symbol at a given text\ndocument position. The request's parameter is of type [TextDocumentPositionParams]\n(#TextDocumentPositionParams) the response is of type [Declaration](#Declaration)\nor a typed array of [DeclarationLink](#DeclarationLink) or a Thenable that resolves\nto such."
+		},
+		{
+			"method": "textDocument/selectionRange",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SelectionRange"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "SelectionRangeParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "SelectionRange"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "SelectionRangeRegistrationOptions"
+			},
+			"documentation": "A request to provide selection ranges in a document. The request's\nparameter is of type [SelectionRangeParams](#SelectionRangeParams), the\nresponse is of type [SelectionRange[]](#SelectionRange[]) or a Thenable\nthat resolves to such."
+		},
+		{
+			"method": "window/workDoneProgress/create",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "WorkDoneProgressCreateParams"
+			},
+			"documentation": "The `window/workDoneProgress/create` request is sent from the server to the client to initiate progress\nreporting from the server."
+		},
+		{
+			"method": "textDocument/prepareCallHierarchy",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CallHierarchyItem"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CallHierarchyPrepareParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "CallHierarchyRegistrationOptions"
+			},
+			"documentation": "A request to result a `CallHierarchyItem` in a document at a given position.\nCan be used as an input to an incoming or outgoing call hierarchy.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "callHierarchy/incomingCalls",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CallHierarchyIncomingCall"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CallHierarchyIncomingCallsParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "CallHierarchyIncomingCall"
+				}
+			},
+			"documentation": "A request to resolve the incoming calls for a given `CallHierarchyItem`.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "callHierarchy/outgoingCalls",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CallHierarchyOutgoingCall"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CallHierarchyOutgoingCallsParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "CallHierarchyOutgoingCall"
+				}
+			},
+			"documentation": "A request to resolve the outgoing calls for a given `CallHierarchyItem`.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/semanticTokens/full",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "SemanticTokens"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "SemanticTokensParams"
+			},
+			"partialResult": {
+				"kind": "reference",
+				"name": "SemanticTokensPartialResult"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "SemanticTokensRegistrationOptions"
+			},
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/semanticTokens/full/delta",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "SemanticTokens"
+					},
+					{
+						"kind": "reference",
+						"name": "SemanticTokensDelta"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "SemanticTokensDeltaParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "SemanticTokensPartialResult"
+					},
+					{
+						"kind": "reference",
+						"name": "SemanticTokensDeltaPartialResult"
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "SemanticTokensRegistrationOptions"
+			},
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/semanticTokens/range",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "SemanticTokens"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "SemanticTokensRangeParams"
+			},
+			"partialResult": {
+				"kind": "reference",
+				"name": "SemanticTokensPartialResult"
+			},
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/semanticTokens/refresh",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "window/showDocument",
+			"result": {
+				"kind": "reference",
+				"name": "ShowDocumentResult"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ShowDocumentParams"
+			},
+			"documentation": "A request to show a document. This request might open an\nexternal program depending on the value of the URI to open.\nFor example a request to open `https://code.visualstudio.com/`\nwill very likely open the URI in a WEB browser.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/linkedEditingRange",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "LinkedEditingRanges"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "LinkedEditingRangeParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "LinkedEditingRangeRegistrationOptions"
+			},
+			"documentation": "A request to provide ranges that can be edited together.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/willCreateFiles",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CreateFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The will create files request is sent from the client to the server before files are actually\ncreated as long as the creation is triggered from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/willRenameFiles",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "RenameFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The will rename files request is sent from the client to the server before files are actually\nrenamed as long as the rename is triggered from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/willDeleteFiles",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DeleteFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The did delete files notification is sent from the client to the server when\nfiles were deleted from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/moniker",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Moniker"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "MonikerParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "Moniker"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "MonikerRegistrationOptions"
+			},
+			"documentation": "A request to get the moniker of a symbol at a given text document position.\nThe request parameter is of type [TextDocumentPositionParams](#TextDocumentPositionParams).\nThe response is of type [Moniker[]](#Moniker[]) or `null`."
+		},
+		{
+			"method": "textDocument/prepareTypeHierarchy",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TypeHierarchyItem"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "TypeHierarchyPrepareParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TypeHierarchyRegistrationOptions"
+			},
+			"documentation": "A request to result a `TypeHierarchyItem` in a document at a given position.\nCan be used as an input to a subtypes or supertypes type hierarchy.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "typeHierarchy/supertypes",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TypeHierarchyItem"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "TypeHierarchySupertypesParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "TypeHierarchyItem"
+				}
+			},
+			"documentation": "A request to resolve the supertypes for a given `TypeHierarchyItem`.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "typeHierarchy/subtypes",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TypeHierarchyItem"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "TypeHierarchySubtypesParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "TypeHierarchyItem"
+				}
+			},
+			"documentation": "A request to resolve the subtypes for a given `TypeHierarchyItem`.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "textDocument/inlineValue",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "InlineValue"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "InlineValueParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "InlineValue"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "InlineValueRegistrationOptions"
+			},
+			"documentation": "A request to provide inline values in a document. The request's parameter is of\ntype [InlineValueParams](#InlineValueParams), the response is of type\n[InlineValue[]](#InlineValue[]) or a Thenable that resolves to such.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "workspace/inlineValue/refresh",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "textDocument/inlayHint",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "InlayHint"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "InlayHintParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "InlayHint"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "InlayHintRegistrationOptions"
+			},
+			"documentation": "A request to provide inlay hints in a document. The request's parameter is of\ntype [InlayHintsParams](#InlayHintsParams), the response is of type\n[InlayHint[]](#InlayHint[]) or a Thenable that resolves to such.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "inlayHint/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "InlayHint"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "InlayHint"
+			},
+			"documentation": "A request to resolve additional properties for an inlay hint.\nThe request's parameter is of type [InlayHint](#InlayHint), the response is\nof type [InlayHint](#InlayHint) or a Thenable that resolves to such.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "workspace/inlayHint/refresh",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "textDocument/diagnostic",
+			"result": {
+				"kind": "reference",
+				"name": "DocumentDiagnosticReport"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentDiagnosticParams"
+			},
+			"partialResult": {
+				"kind": "reference",
+				"name": "DocumentDiagnosticReportPartialResult"
+			},
+			"errorData": {
+				"kind": "reference",
+				"name": "DiagnosticServerCancellationData"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DiagnosticRegistrationOptions"
+			},
+			"documentation": "The document diagnostic request definition.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "workspace/diagnostic",
+			"result": {
+				"kind": "reference",
+				"name": "WorkspaceDiagnosticReport"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "WorkspaceDiagnosticParams"
+			},
+			"partialResult": {
+				"kind": "reference",
+				"name": "WorkspaceDiagnosticReportPartialResult"
+			},
+			"errorData": {
+				"kind": "reference",
+				"name": "DiagnosticServerCancellationData"
+			},
+			"documentation": "The workspace diagnostic request definition.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "workspace/diagnostic/refresh",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "The diagnostic refresh request definition.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "client/registerCapability",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "RegistrationParams"
+			},
+			"documentation": "The `client/registerCapability` request is sent from the server to the client to register a new capability\nhandler on the client side."
+		},
+		{
+			"method": "client/unregisterCapability",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "UnregistrationParams"
+			},
+			"documentation": "The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability\nhandler on the client side."
+		},
+		{
+			"method": "initialize",
+			"result": {
+				"kind": "reference",
+				"name": "InitializeResult"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "InitializeParams"
+			},
+			"errorData": {
+				"kind": "reference",
+				"name": "InitializeError"
+			},
+			"documentation": "The initialize request is sent from the client to the server.\nIt is sent once as the request after starting up the server.\nThe requests parameter is of type [InitializeParams](#InitializeParams)\nthe response if of type [InitializeResult](#InitializeResult) of a Thenable that\nresolves to such."
+		},
+		{
+			"method": "shutdown",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "A shutdown request is sent from the client to the server.\nIt is sent once when the client decides to shutdown the\nserver. The only notification that is sent after a shutdown request\nis the exit event."
+		},
+		{
+			"method": "window/showMessageRequest",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "MessageActionItem"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ShowMessageRequestParams"
+			},
+			"documentation": "The show message request is sent from the server to the client to show a message\nand a set of options actions to the user."
+		},
+		{
+			"method": "textDocument/willSaveWaitUntil",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "WillSaveTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentRegistrationOptions"
+			},
+			"documentation": "A document will save request is sent from the client to the server before\nthe document is actually saved. The request can return an array of TextEdits\nwhich will be applied to the text document before it is saved. Please note that\nclients might drop results if computing the text edits took too long or if a\nserver constantly fails on this request. This is done to keep the save fast and\nreliable."
+		},
+		{
+			"method": "textDocument/completion",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CompletionItem"
+						}
+					},
+					{
+						"kind": "reference",
+						"name": "CompletionList"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CompletionParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "CompletionItem"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "CompletionRegistrationOptions"
+			},
+			"documentation": "Request to request completion at a given text document position. The request's\nparameter is of type [TextDocumentPosition](#TextDocumentPosition) the response\nis of type [CompletionItem[]](#CompletionItem) or [CompletionList](#CompletionList)\nor a Thenable that resolves to such.\n\nThe request can delay the computation of the [`detail`](#CompletionItem.detail)\nand [`documentation`](#CompletionItem.documentation) properties to the `completionItem/resolve`\nrequest. However, properties that are needed for the initial sorting and filtering, like `sortText`,\n`filterText`, `insertText`, and `textEdit`, must not be changed during resolve."
+		},
+		{
+			"method": "completionItem/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "CompletionItem"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CompletionItem"
+			},
+			"documentation": "Request to resolve additional information for a given completion item.The request's\nparameter is of type [CompletionItem](#CompletionItem) the response\nis of type [CompletionItem](#CompletionItem) or a Thenable that resolves to such."
+		},
+		{
+			"method": "textDocument/hover",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Hover"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "HoverParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "HoverRegistrationOptions"
+			},
+			"documentation": "Request to request hover information at a given text document position. The request's\nparameter is of type [TextDocumentPosition](#TextDocumentPosition) the response is of\ntype [Hover](#Hover) or a Thenable that resolves to such."
+		},
+		{
+			"method": "textDocument/signatureHelp",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "SignatureHelp"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "SignatureHelpParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "SignatureHelpRegistrationOptions"
+			}
+		},
+		{
+			"method": "textDocument/definition",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Definition"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DefinitionParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DefinitionLink"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DefinitionRegistrationOptions"
+			},
+			"documentation": "A request to resolve the definition location of a symbol at a given text\ndocument position. The request's parameter is of type [TextDocumentPosition]\n(#TextDocumentPosition) the response is of either type [Definition](#Definition)\nor a typed array of [DefinitionLink](#DefinitionLink) or a Thenable that resolves\nto such."
+		},
+		{
+			"method": "textDocument/references",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ReferenceParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "Location"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "ReferenceRegistrationOptions"
+			},
+			"documentation": "A request to resolve project-wide references for the symbol denoted\nby the given text document position. The request's parameter is of\ntype [ReferenceParams](#ReferenceParams) the response is of type\n[Location[]](#Location) or a Thenable that resolves to such."
+		},
+		{
+			"method": "textDocument/documentHighlight",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DocumentHighlight"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentHighlightParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "DocumentHighlight"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentHighlightRegistrationOptions"
+			},
+			"documentation": "Request to resolve a [DocumentHighlight](#DocumentHighlight) for a given\ntext document position. The request's parameter is of type [TextDocumentPosition]\n(#TextDocumentPosition) the request response is of type [DocumentHighlight[]]\n(#DocumentHighlight) or a Thenable that resolves to such."
+		},
+		{
+			"method": "textDocument/documentSymbol",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolInformation"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DocumentSymbol"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentSymbolParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolInformation"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DocumentSymbol"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentSymbolRegistrationOptions"
+			},
+			"documentation": "A request to list all symbols found in a given text document. The request's\nparameter is of type [TextDocumentIdentifier](#TextDocumentIdentifier) the\nresponse is of type [SymbolInformation[]](#SymbolInformation) or a Thenable\nthat resolves to such."
+		},
+		{
+			"method": "textDocument/codeAction",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "Command"
+								},
+								{
+									"kind": "reference",
+									"name": "CodeAction"
+								}
+							]
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CodeActionParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "or",
+					"items": [
+						{
+							"kind": "reference",
+							"name": "Command"
+						},
+						{
+							"kind": "reference",
+							"name": "CodeAction"
+						}
+					]
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "CodeActionRegistrationOptions"
+			},
+			"documentation": "A request to provide commands for the given text document and range."
+		},
+		{
+			"method": "codeAction/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "CodeAction"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CodeAction"
+			},
+			"documentation": "Request to resolve additional information for a given code action.The request's\nparameter is of type [CodeAction](#CodeAction) the response\nis of type [CodeAction](#CodeAction) or a Thenable that resolves to such."
+		},
+		{
+			"method": "workspace/symbol",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolInformation"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceSymbol"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "WorkspaceSymbolParams"
+			},
+			"partialResult": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolInformation"
+						}
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceSymbol"
+						}
+					}
+				]
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "WorkspaceSymbolRegistrationOptions"
+			},
+			"documentation": "A request to list project-wide symbols matching the query string given\nby the [WorkspaceSymbolParams](#WorkspaceSymbolParams). The response is\nof type [SymbolInformation[]](#SymbolInformation) or a Thenable that\nresolves to such.\n\n@since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients\n need to advertise support for WorkspaceSymbols via the client capability\n `workspace.symbol.resolveSupport`.\n",
+			"since": "3.17.0 - support for WorkspaceSymbol in the returned data. Clients\nneed to advertise support for WorkspaceSymbols via the client capability\n`workspace.symbol.resolveSupport`."
+		},
+		{
+			"method": "workspaceSymbol/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "WorkspaceSymbol"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "WorkspaceSymbol"
+			},
+			"documentation": "A request to resolve the range inside the workspace\nsymbol's location.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "textDocument/codeLens",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CodeLens"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CodeLensParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "CodeLens"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "CodeLensRegistrationOptions"
+			},
+			"documentation": "A request to provide code lens for the given text document."
+		},
+		{
+			"method": "codeLens/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "CodeLens"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "CodeLens"
+			},
+			"documentation": "A request to resolve a command for a given code lens."
+		},
+		{
+			"method": "workspace/codeLens/refresh",
+			"result": {
+				"kind": "base",
+				"name": "null"
+			},
+			"documentation": "A request to refresh all code actions\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "textDocument/documentLink",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DocumentLink"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentLinkParams"
+			},
+			"partialResult": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "DocumentLink"
+				}
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentLinkRegistrationOptions"
+			},
+			"documentation": "A request to provide document links"
+		},
+		{
+			"method": "documentLink/resolve",
+			"result": {
+				"kind": "reference",
+				"name": "DocumentLink"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentLink"
+			},
+			"documentation": "Request to resolve additional information for a given document link. The request's\nparameter is of type [DocumentLink](#DocumentLink) the response\nis of type [DocumentLink](#DocumentLink) or a Thenable that resolves to such."
+		},
+		{
+			"method": "textDocument/formatting",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentFormattingParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentFormattingRegistrationOptions"
+			},
+			"documentation": "A request to to format a whole document."
+		},
+		{
+			"method": "textDocument/rangeFormatting",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentRangeFormattingParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentRangeFormattingRegistrationOptions"
+			},
+			"documentation": "A request to to format a range in a document."
+		},
+		{
+			"method": "textDocument/onTypeFormatting",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "DocumentOnTypeFormattingParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DocumentOnTypeFormattingRegistrationOptions"
+			},
+			"documentation": "A request to format a document on type."
+		},
+		{
+			"method": "textDocument/rename",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "RenameParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "RenameRegistrationOptions"
+			},
+			"documentation": "A request to rename a symbol."
+		},
+		{
+			"method": "textDocument/prepareRename",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "PrepareRenameResult"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "PrepareRenameParams"
+			},
+			"documentation": "A request to test and perform the setup necessary for a rename.\n\n@since 3.16 - support for default behavior",
+			"since": "3.16 - support for default behavior"
+		},
+		{
+			"method": "workspace/executeCommand",
+			"result": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ExecuteCommandParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "ExecuteCommandRegistrationOptions"
+			},
+			"documentation": "A request send from the client to the server to execute a command. The request might return\na workspace edit which the client will apply to the workspace."
+		},
+		{
+			"method": "workspace/applyEdit",
+			"result": {
+				"kind": "reference",
+				"name": "ApplyWorkspaceEditResult"
+			},
+			"params": {
+				"kind": "reference",
+				"name": "ApplyWorkspaceEditParams"
+			},
+			"documentation": "A request sent from the server to the client to modified certain resources."
+		}
+	],
+	"notifications": [
+		{
+			"method": "workspace/didChangeWorkspaceFolders",
+			"params": {
+				"kind": "reference",
+				"name": "DidChangeWorkspaceFoldersParams"
+			},
+			"documentation": "The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace\nfolder configuration changes."
+		},
+		{
+			"method": "window/workDoneProgress/cancel",
+			"params": {
+				"kind": "reference",
+				"name": "WorkDoneProgressCancelParams"
+			},
+			"documentation": "The `window/workDoneProgress/cancel` notification is sent from  the client to the server to cancel a progress\ninitiated on the server side."
+		},
+		{
+			"method": "workspace/didCreateFiles",
+			"params": {
+				"kind": "reference",
+				"name": "CreateFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The did create files notification is sent from the client to the server when\nfiles were created from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/didRenameFiles",
+			"params": {
+				"kind": "reference",
+				"name": "RenameFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The did rename files notification is sent from the client to the server when\nfiles were renamed from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "workspace/didDeleteFiles",
+			"params": {
+				"kind": "reference",
+				"name": "DeleteFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "FileOperationRegistrationOptions"
+			},
+			"documentation": "The will delete files request is sent from the client to the server before files are actually\ndeleted as long as the deletion is triggered from within the client.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"method": "notebookDocument/didOpen",
+			"params": {
+				"kind": "reference",
+				"name": "DidOpenNotebookDocumentParams"
+			},
+			"documentation": "A notification sent when a notebook opens.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "notebookDocument/didChange",
+			"params": {
+				"kind": "reference",
+				"name": "DidChangeNotebookDocumentParams"
+			}
+		},
+		{
+			"method": "notebookDocument/didSave",
+			"params": {
+				"kind": "reference",
+				"name": "DidSaveNotebookDocumentParams"
+			},
+			"documentation": "A notification sent when a notebook document is saved.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "notebookDocument/didClose",
+			"params": {
+				"kind": "reference",
+				"name": "DidCloseNotebookDocumentParams"
+			},
+			"documentation": "A notification sent when a notebook closes.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"method": "initialized",
+			"params": {
+				"kind": "reference",
+				"name": "InitializedParams"
+			},
+			"documentation": "The initialized notification is sent from the client to the\nserver after the client is fully initialized and the server\nis allowed to send requests from the server to the client."
+		},
+		{
+			"method": "exit",
+			"documentation": "The exit event is sent from the client to the server to\nask the server to exit its process."
+		},
+		{
+			"method": "workspace/didChangeConfiguration",
+			"params": {
+				"kind": "reference",
+				"name": "DidChangeConfigurationParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DidChangeConfigurationRegistrationOptions"
+			},
+			"documentation": "The configuration change notification is sent from the client to the server\nwhen the client's configuration has changed. The notification contains\nthe changed configuration as defined by the language client."
+		},
+		{
+			"method": "window/showMessage",
+			"params": {
+				"kind": "reference",
+				"name": "ShowMessageParams"
+			},
+			"documentation": "The show message notification is sent from a server to a client to ask\nthe client to display a particular message in the user interface."
+		},
+		{
+			"method": "window/logMessage",
+			"params": {
+				"kind": "reference",
+				"name": "LogMessageParams"
+			},
+			"documentation": "The log message notification is sent from the server to the client to ask\nthe client to log a particular message."
+		},
+		{
+			"method": "telemetry/event",
+			"params": {
+				"kind": "reference",
+				"name": "LSPAny"
+			},
+			"documentation": "The telemetry event notification is sent from the server to the client to ask\nthe client to log telemetry data."
+		},
+		{
+			"method": "textDocument/didOpen",
+			"params": {
+				"kind": "reference",
+				"name": "DidOpenTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentRegistrationOptions"
+			},
+			"documentation": "The document open notification is sent from the client to the server to signal\nnewly opened text documents. The document's truth is now managed by the client\nand the server must not try to read the document's truth using the document's\nuri. Open in this sense means it is managed by the client. It doesn't necessarily\nmean that its content is presented in an editor. An open notification must not\nbe sent more than once without a corresponding close notification send before.\nThis means open and close notification must be balanced and the max open count\nis one."
+		},
+		{
+			"method": "textDocument/didChange",
+			"params": {
+				"kind": "reference",
+				"name": "DidChangeTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentChangeRegistrationOptions"
+			},
+			"documentation": "The document change notification is sent from the client to the server to signal\nchanges to a text document."
+		},
+		{
+			"method": "textDocument/didClose",
+			"params": {
+				"kind": "reference",
+				"name": "DidCloseTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentRegistrationOptions"
+			},
+			"documentation": "The document close notification is sent from the client to the server when\nthe document got closed in the client. The document's truth now exists where\nthe document's uri points to (e.g. if the document's uri is a file uri the\ntruth now exists on disk). As with the open notification the close notification\nis about managing the document's content. Receiving a close notification\ndoesn't mean that the document was open in an editor before. A close\nnotification requires a previous open notification to be sent."
+		},
+		{
+			"method": "textDocument/didSave",
+			"params": {
+				"kind": "reference",
+				"name": "DidSaveTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentSaveRegistrationOptions"
+			},
+			"documentation": "The document save notification is sent from the client to the server when\nthe document got saved in the client."
+		},
+		{
+			"method": "textDocument/willSave",
+			"params": {
+				"kind": "reference",
+				"name": "WillSaveTextDocumentParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "TextDocumentRegistrationOptions"
+			},
+			"documentation": "A document will save notification is sent from the client to the server before\nthe document is actually saved."
+		},
+		{
+			"method": "workspace/didChangeWatchedFiles",
+			"params": {
+				"kind": "reference",
+				"name": "DidChangeWatchedFilesParams"
+			},
+			"registrationOptions": {
+				"kind": "reference",
+				"name": "DidChangeWatchedFilesRegistrationOptions"
+			},
+			"documentation": "The watched files notification is sent from the client to the server when\nthe client detects changes to file watched by the language client."
+		},
+		{
+			"method": "textDocument/publishDiagnostics",
+			"params": {
+				"kind": "reference",
+				"name": "PublishDiagnosticsParams"
+			},
+			"documentation": "Diagnostics notification are sent from the server to the client to signal\nresults of validation runs."
+		},
+		{
+			"method": "$/setTrace",
+			"params": {
+				"kind": "reference",
+				"name": "SetTraceParams"
+			}
+		},
+		{
+			"method": "$/logTrace",
+			"params": {
+				"kind": "reference",
+				"name": "LogTraceParams"
+			}
+		},
+		{
+			"method": "$/cancelRequest",
+			"params": {
+				"kind": "reference",
+				"name": "CancelParams"
+			}
+		},
+		{
+			"method": "$/progress",
+			"params": {
+				"kind": "reference",
+				"name": "ProgressParams"
+			}
+		}
+	],
+	"structures": [
+		{
+			"name": "ImplementationParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			]
+		},
+		{
+			"name": "Location",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					}
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					}
+				}
+			],
+			"documentation": "Represents a location inside a resource, such as a line\ninside a text file."
+		},
+		{
+			"name": "ImplementationRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "ImplementationOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "TypeDefinitionParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			]
+		},
+		{
+			"name": "TypeDefinitionRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TypeDefinitionOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "WorkspaceFolder",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "The associated URI for this workspace folder."
+				},
+				{
+					"name": "name",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of the workspace folder. Used to refer to this\nworkspace folder in the user interface."
+				}
+			],
+			"documentation": "A workspace folder inside a client."
+		},
+		{
+			"name": "DidChangeWorkspaceFoldersParams",
+			"properties": [
+				{
+					"name": "event",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceFoldersChangeEvent"
+					},
+					"documentation": "The actual workspace folder change event."
+				}
+			],
+			"documentation": "The parameters of a `workspace/didChangeWorkspaceFolders` notification."
+		},
+		{
+			"name": "ConfigurationParams",
+			"properties": [
+				{
+					"name": "items",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "ConfigurationItem"
+						}
+					}
+				}
+			],
+			"documentation": "The parameters of a configuration request."
+		},
+		{
+			"name": "PartialResultParams",
+			"properties": [
+				{
+					"name": "partialResultToken",
+					"type": {
+						"kind": "reference",
+						"name": "ProgressToken"
+					},
+					"optional": true,
+					"documentation": "An optional token that a server can use to report partial results (e.g. streaming) to\nthe client."
+				}
+			]
+		},
+		{
+			"name": "DocumentColorParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [DocumentColorRequest](#DocumentColorRequest)."
+		},
+		{
+			"name": "ColorInformation",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range in the document where this color appears."
+				},
+				{
+					"name": "color",
+					"type": {
+						"kind": "reference",
+						"name": "Color"
+					},
+					"documentation": "The actual color value for this color range."
+				}
+			],
+			"documentation": "Represents a color range from a document."
+		},
+		{
+			"name": "DocumentColorRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentColorOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "ColorPresentationParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "color",
+					"type": {
+						"kind": "reference",
+						"name": "Color"
+					},
+					"documentation": "The color to request presentations for."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range where the color would be inserted. Serves as a context."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [ColorPresentationRequest](#ColorPresentationRequest)."
+		},
+		{
+			"name": "ColorPresentation",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The label of this color presentation. It will be shown on the color\npicker header. By default this is also the text that is inserted when selecting\nthis color presentation."
+				},
+				{
+					"name": "textEdit",
+					"type": {
+						"kind": "reference",
+						"name": "TextEdit"
+					},
+					"optional": true,
+					"documentation": "An [edit](#TextEdit) which is applied to a document when selecting\nthis presentation for the color.  When `falsy` the [label](#ColorPresentation.label)\nis used."
+				},
+				{
+					"name": "additionalTextEdits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					"optional": true,
+					"documentation": "An optional array of additional [text edits](#TextEdit) that are applied when\nselecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves."
+				}
+			]
+		},
+		{
+			"name": "WorkDoneProgressOptions",
+			"properties": [
+				{
+					"name": "workDoneProgress",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true
+				}
+			]
+		},
+		{
+			"name": "TextDocumentRegistrationOptions",
+			"properties": [
+				{
+					"name": "documentSelector",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "DocumentSelector"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "A document selector to identify the scope of the registration. If set to null\nthe document selector provided on the client side will be used."
+				}
+			],
+			"documentation": "General text document registration options."
+		},
+		{
+			"name": "FoldingRangeParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [FoldingRangeRequest](#FoldingRangeRequest)."
+		},
+		{
+			"name": "FoldingRange",
+			"properties": [
+				{
+					"name": "startLine",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The zero-based start line of the range to fold. The folded area starts after the line's last character.\nTo be valid, the end must be zero or larger and smaller than the number of lines in the document."
+				},
+				{
+					"name": "startCharacter",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line."
+				},
+				{
+					"name": "endLine",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The zero-based end line of the range to fold. The folded area ends with the line's last character.\nTo be valid, the end must be zero or larger and smaller than the number of lines in the document."
+				},
+				{
+					"name": "endCharacter",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "FoldingRangeKind"
+					},
+					"optional": true,
+					"documentation": "Describes the kind of the folding range such as `comment' or 'region'. The kind\nis used to categorize folding ranges and used by commands like 'Fold all comments'.\nSee [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds."
+				},
+				{
+					"name": "collapsedText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The text that the client should show when the specified range is\ncollapsed. If not defined or not supported by the client, a default\nwill be chosen by the client.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Represents a folding range. To be valid, start and end line must be bigger than zero and smaller\nthan the number of lines in the document. Clients are free to ignore invalid ranges."
+		},
+		{
+			"name": "FoldingRangeRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "FoldingRangeOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "DeclarationParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			]
+		},
+		{
+			"name": "DeclarationRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "DeclarationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "SelectionRangeParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "positions",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Position"
+						}
+					},
+					"documentation": "The positions inside the text document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "A parameter literal used in selection range requests."
+		},
+		{
+			"name": "SelectionRange",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The [range](#Range) of this selection range."
+				},
+				{
+					"name": "parent",
+					"type": {
+						"kind": "reference",
+						"name": "SelectionRange"
+					},
+					"optional": true,
+					"documentation": "The parent selection range containing this range. Therefore `parent.range` must contain `this.range`."
+				}
+			],
+			"documentation": "A selection range represents a part of a selection hierarchy. A selection range\nmay have a parent selection range that contains it."
+		},
+		{
+			"name": "SelectionRangeRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "SelectionRangeOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "WorkDoneProgressCreateParams",
+			"properties": [
+				{
+					"name": "token",
+					"type": {
+						"kind": "reference",
+						"name": "ProgressToken"
+					},
+					"documentation": "The token to be used to report progress."
+				}
+			]
+		},
+		{
+			"name": "WorkDoneProgressCancelParams",
+			"properties": [
+				{
+					"name": "token",
+					"type": {
+						"kind": "reference",
+						"name": "ProgressToken"
+					},
+					"documentation": "The token to be used to report progress."
+				}
+			]
+		},
+		{
+			"name": "CallHierarchyPrepareParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameter of a `textDocument/prepareCallHierarchy` request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyItem",
+			"properties": [
+				{
+					"name": "name",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of this item."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "SymbolKind"
+					},
+					"documentation": "The kind of this item."
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Tags for this item."
+				},
+				{
+					"name": "detail",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "More detail for this item, e.g. the signature of a function."
+				},
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The resource identifier of this item."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code."
+				},
+				{
+					"name": "selectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.\nMust be contained by the [`range`](#CallHierarchyItem.range)."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved between a call hierarchy prepare and\nincoming calls or outgoing calls requests."
+				}
+			],
+			"documentation": "Represents programming constructs like functions or constructors in the context\nof call hierarchy.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "CallHierarchyOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Call hierarchy options used during static or dynamic registration.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyIncomingCallsParams",
+			"properties": [
+				{
+					"name": "item",
+					"type": {
+						"kind": "reference",
+						"name": "CallHierarchyItem"
+					}
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameter of a `callHierarchy/incomingCalls` request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyIncomingCall",
+			"properties": [
+				{
+					"name": "from",
+					"type": {
+						"kind": "reference",
+						"name": "CallHierarchyItem"
+					},
+					"documentation": "The item that makes the call."
+				},
+				{
+					"name": "fromRanges",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Range"
+						}
+					},
+					"documentation": "The ranges at which the calls appear. This is relative to the caller\ndenoted by [`this.from`](#CallHierarchyIncomingCall.from)."
+				}
+			],
+			"documentation": "Represents an incoming call, e.g. a caller of a method or constructor.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyOutgoingCallsParams",
+			"properties": [
+				{
+					"name": "item",
+					"type": {
+						"kind": "reference",
+						"name": "CallHierarchyItem"
+					}
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameter of a `callHierarchy/outgoingCalls` request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CallHierarchyOutgoingCall",
+			"properties": [
+				{
+					"name": "to",
+					"type": {
+						"kind": "reference",
+						"name": "CallHierarchyItem"
+					},
+					"documentation": "The item that is called."
+				},
+				{
+					"name": "fromRanges",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Range"
+						}
+					},
+					"documentation": "The range at which this item is called. This is the range relative to the caller, e.g the item\npassed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)\nand not [`this.to`](#CallHierarchyOutgoingCall.to)."
+				}
+			],
+			"documentation": "Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokens",
+			"properties": [
+				{
+					"name": "resultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional result id. If provided and clients support delta updating\nthe client will include the result id in the next semantic token request.\nA server can then instead of computing all semantic tokens again simply\nsend a delta."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "uinteger"
+						}
+					},
+					"documentation": "The actual tokens."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensPartialResult",
+			"properties": [
+				{
+					"name": "data",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "uinteger"
+						}
+					}
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "SemanticTokensOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensDeltaParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "previousResultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The result id of a previous response. The result Id can either point to a full response\nor a delta response depending on what was received last."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensDelta",
+			"properties": [
+				{
+					"name": "resultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true
+				},
+				{
+					"name": "edits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SemanticTokensEdit"
+						}
+					},
+					"documentation": "The semantic token edits to transform a previous result into a new result."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensDeltaPartialResult",
+			"properties": [
+				{
+					"name": "edits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SemanticTokensEdit"
+						}
+					}
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensRangeParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range the semantic tokens are requested for."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "ShowDocumentParams",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "The document uri to show."
+				},
+				{
+					"name": "external",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Indicates to show the resource in an external program.\nTo show for example `https://code.visualstudio.com/`\nin the default WEB browser set `external` to `true`."
+				},
+				{
+					"name": "takeFocus",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "An optional property to indicate whether the editor\nshowing the document should take focus or not.\nClients might ignore this property if an external\nprogram is started."
+				},
+				{
+					"name": "selection",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"optional": true,
+					"documentation": "An optional selection range if the document is a text\ndocument. Clients might ignore the property if an\nexternal program is started or the file is not a text\nfile."
+				}
+			],
+			"documentation": "Params to show a document.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "ShowDocumentResult",
+			"properties": [
+				{
+					"name": "success",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "A boolean indicating if the show was successful."
+				}
+			],
+			"documentation": "The result of a showDocument request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "LinkedEditingRangeParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			]
+		},
+		{
+			"name": "LinkedEditingRanges",
+			"properties": [
+				{
+					"name": "ranges",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Range"
+						}
+					},
+					"documentation": "A list of ranges that can be edited together. The ranges must have\nidentical length and contain identical text content. The ranges cannot overlap."
+				},
+				{
+					"name": "wordPattern",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional word pattern (regular expression) that describes valid contents for\nthe given ranges. If no pattern is provided, the client configuration's word\npattern will be used."
+				}
+			],
+			"documentation": "The result of a linked editing range request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "LinkedEditingRangeRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "LinkedEditingRangeOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			]
+		},
+		{
+			"name": "CreateFilesParams",
+			"properties": [
+				{
+					"name": "files",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileCreate"
+						}
+					},
+					"documentation": "An array of all files/folders created in this operation."
+				}
+			],
+			"documentation": "The parameters sent in notifications/requests for user-initiated creation of\nfiles.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "WorkspaceEdit",
+			"properties": [
+				{
+					"name": "changes",
+					"type": {
+						"kind": "map",
+						"key": {
+							"kind": "base",
+							"name": "DocumentUri"
+						},
+						"value": {
+							"kind": "array",
+							"element": {
+								"kind": "reference",
+								"name": "TextEdit"
+							}
+						}
+					},
+					"optional": true,
+					"documentation": "Holds changes to existing resources."
+				},
+				{
+					"name": "documentChanges",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "TextDocumentEdit"
+								},
+								{
+									"kind": "reference",
+									"name": "CreateFile"
+								},
+								{
+									"kind": "reference",
+									"name": "RenameFile"
+								},
+								{
+									"kind": "reference",
+									"name": "DeleteFile"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes\nare either an array of `TextDocumentEdit`s to express changes to n different text documents\nwhere each text document edit addresses a specific version of a text document. Or it can contain\nabove `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.\n\nWhether a client supports versioned document edits is expressed via\n`workspace.workspaceEdit.documentChanges` client capability.\n\nIf a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then\nonly plain `TextEdit`s using the `changes` property are supported."
+				},
+				{
+					"name": "changeAnnotations",
+					"type": {
+						"kind": "map",
+						"key": {
+							"kind": "reference",
+							"name": "ChangeAnnotationIdentifier"
+						},
+						"value": {
+							"kind": "reference",
+							"name": "ChangeAnnotation"
+						}
+					},
+					"optional": true,
+					"documentation": "A map of change annotations that can be referenced in `AnnotatedTextEdit`s or create, rename and\ndelete file / folder operations.\n\nWhether clients honor this property depends on the client capability `workspace.changeAnnotationSupport`.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "A workspace edit represents changes to many resources managed in the workspace. The edit\nshould either provide `changes` or `documentChanges`. If documentChanges are present\nthey are preferred over `changes` if the client can handle versioned document edits.\n\nSince version 3.13.0 a workspace edit can contain resource operations as well. If resource\noperations are present clients need to execute the operations in the order in which they\nare provided. So a workspace edit for example can consist of the following two changes:\n(1) a create file a.txt and (2) a text document edit which insert text into file a.txt.\n\nAn invalid sequence (e.g. (1) delete file a.txt and (2) insert text into file a.txt) will\ncause failure of the operation. How the client recovers from the failure is described by\nthe client capability: `workspace.workspaceEdit.failureHandling`"
+		},
+		{
+			"name": "FileOperationRegistrationOptions",
+			"properties": [
+				{
+					"name": "filters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileOperationFilter"
+						}
+					},
+					"documentation": "The actual filters."
+				}
+			],
+			"documentation": "The options to register for file operations.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "RenameFilesParams",
+			"properties": [
+				{
+					"name": "files",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileRename"
+						}
+					},
+					"documentation": "An array of all files/folders renamed in this operation. When a folder is renamed, only\nthe folder will be included, and not its children."
+				}
+			],
+			"documentation": "The parameters sent in notifications/requests for user-initiated renames of\nfiles.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "DeleteFilesParams",
+			"properties": [
+				{
+					"name": "files",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileDelete"
+						}
+					},
+					"documentation": "An array of all files/folders deleted in this operation."
+				}
+			],
+			"documentation": "The parameters sent in notifications/requests for user-initiated deletes of\nfiles.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MonikerParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			]
+		},
+		{
+			"name": "Moniker",
+			"properties": [
+				{
+					"name": "scheme",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The scheme of the moniker. For example tsc or .Net"
+				},
+				{
+					"name": "identifier",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The identifier of the moniker. The value is opaque in LSIF however\nschema owners are allowed to define the structure if they want."
+				},
+				{
+					"name": "unique",
+					"type": {
+						"kind": "reference",
+						"name": "UniquenessLevel"
+					},
+					"documentation": "The scope in which the moniker is unique"
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "MonikerKind"
+					},
+					"optional": true,
+					"documentation": "The moniker kind if known."
+				}
+			],
+			"documentation": "Moniker definition to match LSIF 0.5 moniker definition.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MonikerRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "MonikerOptions"
+				}
+			]
+		},
+		{
+			"name": "TypeHierarchyPrepareParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameter of a `textDocument/prepareTypeHierarchy` request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TypeHierarchyItem",
+			"properties": [
+				{
+					"name": "name",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of this item."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "SymbolKind"
+					},
+					"documentation": "The kind of this item."
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Tags for this item."
+				},
+				{
+					"name": "detail",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "More detail for this item, e.g. the signature of a function."
+				},
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The resource identifier of this item."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range enclosing this symbol not including leading/trailing whitespace\nbut everything else, e.g. comments and code."
+				},
+				{
+					"name": "selectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range that should be selected and revealed when this symbol is being\npicked, e.g. the name of a function. Must be contained by the\n[`range`](#TypeHierarchyItem.range)."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved between a type hierarchy prepare and\nsupertypes or subtypes requests. It could also be used to identify the\ntype hierarchy in the server, helping improve the performance on\nresolving supertypes and subtypes."
+				}
+			],
+			"documentation": "@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TypeHierarchyRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TypeHierarchyOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Type hierarchy options used during static or dynamic registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TypeHierarchySupertypesParams",
+			"properties": [
+				{
+					"name": "item",
+					"type": {
+						"kind": "reference",
+						"name": "TypeHierarchyItem"
+					}
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameter of a `typeHierarchy/supertypes` request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TypeHierarchySubtypesParams",
+			"properties": [
+				{
+					"name": "item",
+					"type": {
+						"kind": "reference",
+						"name": "TypeHierarchyItem"
+					}
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameter of a `typeHierarchy/subtypes` request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range for which inline values should be computed."
+				},
+				{
+					"name": "context",
+					"type": {
+						"kind": "reference",
+						"name": "InlineValueContext"
+					},
+					"documentation": "Additional information about the context in which inline values were\nrequested."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "A parameter literal used in inline value requests.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "InlineValueOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Inline value options used during static or dynamic registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHintParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range for which inlay hints should be computed."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "A parameter literal used in inlay hint requests.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHint",
+			"properties": [
+				{
+					"name": "position",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The position of this hint."
+				},
+				{
+					"name": "label",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "array",
+								"element": {
+									"kind": "reference",
+									"name": "InlayHintLabelPart"
+								}
+							}
+						]
+					},
+					"documentation": "The label of this hint. A human readable string or an array of\nInlayHintLabelPart label parts.\n\n*Note* that neither the string nor the label part can be empty."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "InlayHintKind"
+					},
+					"optional": true,
+					"documentation": "The kind of this hint. Can be omitted in which case the client\nshould fall back to a reasonable default."
+				},
+				{
+					"name": "textEdits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					"optional": true,
+					"documentation": "Optional text edits that are performed when accepting this inlay hint.\n\n*Note* that edits are expected to change the document so that the inlay\nhint (or its nearest variant) is now part of the document and the inlay\nhint itself is now obsolete."
+				},
+				{
+					"name": "tooltip",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The tooltip text when you hover over this item."
+				},
+				{
+					"name": "paddingLeft",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Render padding before the hint.\n\nNote: Padding should use the editor's background color, not the\nbackground color of the hint itself. That means padding can be used\nto visually align/separate an inlay hint."
+				},
+				{
+					"name": "paddingRight",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Render padding after the hint.\n\nNote: Padding should use the editor's background color, not the\nbackground color of the hint itself. That means padding can be used\nto visually align/separate an inlay hint."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on an inlay hint between\na `textDocument/inlayHint` and a `inlayHint/resolve` request."
+				}
+			],
+			"documentation": "Inlay hint information.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHintRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "InlayHintOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Inlay hint options used during static or dynamic registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DocumentDiagnosticParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "identifier",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The additional identifier  provided during registration."
+				},
+				{
+					"name": "previousResultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The result id of a previous response if provided."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters of the document diagnostic request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DocumentDiagnosticReportPartialResult",
+			"properties": [
+				{
+					"name": "relatedDocuments",
+					"type": {
+						"kind": "map",
+						"key": {
+							"kind": "base",
+							"name": "DocumentUri"
+						},
+						"value": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "FullDocumentDiagnosticReport"
+								},
+								{
+									"kind": "reference",
+									"name": "UnchangedDocumentDiagnosticReport"
+								}
+							]
+						}
+					}
+				}
+			],
+			"documentation": "A partial result for a document diagnostic report.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DiagnosticServerCancellationData",
+			"properties": [
+				{
+					"name": "retriggerRequest",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					}
+				}
+			],
+			"documentation": "Cancellation data returned from a diagnostic request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DiagnosticRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DiagnosticOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Diagnostic registration options.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceDiagnosticParams",
+			"properties": [
+				{
+					"name": "identifier",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The additional identifier provided during registration."
+				},
+				{
+					"name": "previousResultIds",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "PreviousResultId"
+						}
+					},
+					"documentation": "The currently known diagnostic reports with their\nprevious result ids."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters of the workspace diagnostic request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceDiagnosticReport",
+			"properties": [
+				{
+					"name": "items",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceDocumentDiagnosticReport"
+						}
+					}
+				}
+			],
+			"documentation": "A workspace diagnostic report.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceDiagnosticReportPartialResult",
+			"properties": [
+				{
+					"name": "items",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceDocumentDiagnosticReport"
+						}
+					}
+				}
+			],
+			"documentation": "A partial result for a workspace diagnostic report.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DidOpenNotebookDocumentParams",
+			"properties": [
+				{
+					"name": "notebookDocument",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocument"
+					},
+					"documentation": "The notebook document that got opened."
+				},
+				{
+					"name": "cellTextDocuments",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextDocumentItem"
+						}
+					},
+					"documentation": "The text documents that represent the content\nof a notebook cell."
+				}
+			],
+			"documentation": "The params sent in an open notebook document notification.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DidChangeNotebookDocumentParams",
+			"properties": [
+				{
+					"name": "notebookDocument",
+					"type": {
+						"kind": "reference",
+						"name": "VersionedNotebookDocumentIdentifier"
+					},
+					"documentation": "The notebook document that did change. The version number points\nto the version after all provided changes have been applied. If\nonly the text document content of a cell changes the notebook version\ndoesn't necessarily have to change."
+				},
+				{
+					"name": "change",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocumentChangeEvent"
+					},
+					"documentation": "The actual changes to the notebook document.\n\nThe changes describe single state changes to the notebook document.\nSo if there are two changes c1 (at array index 0) and c2 (at array\nindex 1) for a notebook in state S then c1 moves the notebook from\nS to S' and c2 from S' to S''. So c1 is computed on the state S and\nc2 is computed on the state S'.\n\nTo mirror the content of a notebook using change events use the following approach:\n- start with the same initial content\n- apply the 'notebookDocument/didChange' notifications in the order you receive them.\n- apply the `NotebookChangeEvent`s in a single notification in the order\n  you receive them."
+				}
+			],
+			"documentation": "The params sent in a change notebook document notification.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DidSaveNotebookDocumentParams",
+			"properties": [
+				{
+					"name": "notebookDocument",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocumentIdentifier"
+					},
+					"documentation": "The notebook document that got saved."
+				}
+			],
+			"documentation": "The params sent in a save notebook document notification.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DidCloseNotebookDocumentParams",
+			"properties": [
+				{
+					"name": "notebookDocument",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocumentIdentifier"
+					},
+					"documentation": "The notebook document that got closed."
+				},
+				{
+					"name": "cellTextDocuments",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextDocumentIdentifier"
+						}
+					},
+					"documentation": "The text documents that represent the content\nof a notebook cell that got closed."
+				}
+			],
+			"documentation": "The params sent in a close notebook document notification.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "RegistrationParams",
+			"properties": [
+				{
+					"name": "registrations",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Registration"
+						}
+					}
+				}
+			]
+		},
+		{
+			"name": "UnregistrationParams",
+			"properties": [
+				{
+					"name": "unregisterations",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Unregistration"
+						}
+					}
+				}
+			]
+		},
+		{
+			"name": "InitializeParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "_InitializeParams"
+				},
+				{
+					"kind": "reference",
+					"name": "WorkspaceFoldersInitializeParams"
+				}
+			]
+		},
+		{
+			"name": "InitializeResult",
+			"properties": [
+				{
+					"name": "capabilities",
+					"type": {
+						"kind": "reference",
+						"name": "ServerCapabilities"
+					},
+					"documentation": "The capabilities the language server provides."
+				},
+				{
+					"name": "serverInfo",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "name",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "The name of the server as defined by the server."
+								},
+								{
+									"name": "version",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "The server's version as defined by the server."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Information about the server.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"documentation": "The result returned from an initialize request."
+		},
+		{
+			"name": "InitializeError",
+			"properties": [
+				{
+					"name": "retry",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "Indicates whether the client execute the following retry logic:\n(1) show the message provided by the ResponseError to the user\n(2) user selects retry or cancel\n(3) if user selected retry the initialize method is sent again."
+				}
+			],
+			"documentation": "The data type of the ResponseError if the\ninitialize request fails."
+		},
+		{
+			"name": "InitializedParams",
+			"properties": []
+		},
+		{
+			"name": "DidChangeConfigurationParams",
+			"properties": [
+				{
+					"name": "settings",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"documentation": "The actual changed settings"
+				}
+			],
+			"documentation": "The parameters of a change configuration notification."
+		},
+		{
+			"name": "DidChangeConfigurationRegistrationOptions",
+			"properties": [
+				{
+					"name": "section",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "array",
+								"element": {
+									"kind": "base",
+									"name": "string"
+								}
+							}
+						]
+					},
+					"optional": true
+				}
+			]
+		},
+		{
+			"name": "ShowMessageParams",
+			"properties": [
+				{
+					"name": "type",
+					"type": {
+						"kind": "reference",
+						"name": "MessageType"
+					},
+					"documentation": "The message type. See {@link MessageType}"
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The actual message."
+				}
+			],
+			"documentation": "The parameters of a notification message."
+		},
+		{
+			"name": "ShowMessageRequestParams",
+			"properties": [
+				{
+					"name": "type",
+					"type": {
+						"kind": "reference",
+						"name": "MessageType"
+					},
+					"documentation": "The message type. See {@link MessageType}"
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The actual message."
+				},
+				{
+					"name": "actions",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "MessageActionItem"
+						}
+					},
+					"optional": true,
+					"documentation": "The message action items to present."
+				}
+			]
+		},
+		{
+			"name": "MessageActionItem",
+			"properties": [
+				{
+					"name": "title",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A short title like 'Retry', 'Open Log' etc."
+				}
+			]
+		},
+		{
+			"name": "LogMessageParams",
+			"properties": [
+				{
+					"name": "type",
+					"type": {
+						"kind": "reference",
+						"name": "MessageType"
+					},
+					"documentation": "The message type. See {@link MessageType}"
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The actual message."
+				}
+			],
+			"documentation": "The log message parameters."
+		},
+		{
+			"name": "DidOpenTextDocumentParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentItem"
+					},
+					"documentation": "The document that was opened."
+				}
+			],
+			"documentation": "The parameters sent in an open text document notification"
+		},
+		{
+			"name": "DidChangeTextDocumentParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "VersionedTextDocumentIdentifier"
+					},
+					"documentation": "The document that did change. The version number points\nto the version after all provided content changes have\nbeen applied."
+				},
+				{
+					"name": "contentChanges",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextDocumentContentChangeEvent"
+						}
+					},
+					"documentation": "The actual content changes. The content changes describe single state changes\nto the document. So if there are two content changes c1 (at array index 0) and\nc2 (at array index 1) for a document in state S then c1 moves the document from\nS to S' and c2 from S' to S''. So c1 is computed on the state S and c2 is computed\non the state S'.\n\nTo mirror the content of a document using change events use the following approach:\n- start with the same initial content\n- apply the 'textDocument/didChange' notifications in the order you receive them.\n- apply the `TextDocumentContentChangeEvent`s in a single notification in the order\n  you receive them."
+				}
+			],
+			"documentation": "The change text document notification's parameters."
+		},
+		{
+			"name": "TextDocumentChangeRegistrationOptions",
+			"properties": [
+				{
+					"name": "syncKind",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentSyncKind"
+					},
+					"documentation": "How documents are synced to the server."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				}
+			],
+			"documentation": "Describe options to be used when registered for text document change events."
+		},
+		{
+			"name": "DidCloseTextDocumentParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document that was closed."
+				}
+			],
+			"documentation": "The parameters sent in a close text document notification"
+		},
+		{
+			"name": "DidSaveTextDocumentParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document that was saved."
+				},
+				{
+					"name": "text",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "Optional the content when saved. Depends on the includeText value\nwhen the save notification was requested."
+				}
+			],
+			"documentation": "The parameters sent in a save text document notification"
+		},
+		{
+			"name": "TextDocumentSaveRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "SaveOptions"
+				}
+			],
+			"documentation": "Save registration options."
+		},
+		{
+			"name": "WillSaveTextDocumentParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document that will be saved."
+				},
+				{
+					"name": "reason",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentSaveReason"
+					},
+					"documentation": "The 'TextDocumentSaveReason'."
+				}
+			],
+			"documentation": "The parameters sent in a will save text document notification."
+		},
+		{
+			"name": "TextEdit",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range of the text document to be manipulated. To insert\ntext into a document create a range where start === end."
+				},
+				{
+					"name": "newText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The string to be inserted. For delete operations use an\nempty string."
+				}
+			],
+			"documentation": "A text edit applicable to a text document."
+		},
+		{
+			"name": "DidChangeWatchedFilesParams",
+			"properties": [
+				{
+					"name": "changes",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileEvent"
+						}
+					},
+					"documentation": "The actual file events."
+				}
+			],
+			"documentation": "The watched files change notification's parameters."
+		},
+		{
+			"name": "DidChangeWatchedFilesRegistrationOptions",
+			"properties": [
+				{
+					"name": "watchers",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "FileSystemWatcher"
+						}
+					},
+					"documentation": "The watchers to register."
+				}
+			],
+			"documentation": "Describe options to be used when registered for text document change events."
+		},
+		{
+			"name": "PublishDiagnosticsParams",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The URI for which diagnostic information is reported."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"optional": true,
+					"documentation": "Optional the version number of the document the diagnostics are published for.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "diagnostics",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Diagnostic"
+						}
+					},
+					"documentation": "An array of diagnostic information items."
+				}
+			],
+			"documentation": "The publish diagnostic notification's parameters."
+		},
+		{
+			"name": "CompletionParams",
+			"properties": [
+				{
+					"name": "context",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionContext"
+					},
+					"optional": true,
+					"documentation": "The completion context. This is only available it the client specifies\nto send this using the client capability `textDocument.completion.contextSupport === true`"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Completion parameters"
+		},
+		{
+			"name": "CompletionItem",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The label of this completion item.\n\nThe label property is also by default the text that\nis inserted when selecting this completion.\n\nIf label details are provided the label itself should\nbe an unqualified name of the completion item."
+				},
+				{
+					"name": "labelDetails",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionItemLabelDetails"
+					},
+					"optional": true,
+					"documentation": "Additional details for the label\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionItemKind"
+					},
+					"optional": true,
+					"documentation": "The kind of this completion item. Based of the kind\nan icon is chosen by the editor."
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CompletionItemTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Tags for this completion item.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "detail",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A human-readable string with additional information\nabout this item, like type or symbol information."
+				},
+				{
+					"name": "documentation",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "A human-readable string that represents a doc-comment."
+				},
+				{
+					"name": "deprecated",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Indicates if this item is deprecated.\n@deprecated Use `tags` instead."
+				},
+				{
+					"name": "preselect",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Select this item when showing.\n\n*Note* that only one completion item can be selected and that the\ntool / client decides which item that is. The rule is that the *first*\nitem of those that match best is selected."
+				},
+				{
+					"name": "sortText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A string that should be used when comparing this item\nwith other items. When `falsy` the [label](#CompletionItem.label)\nis used."
+				},
+				{
+					"name": "filterText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A string that should be used when filtering a set of\ncompletion items. When `falsy` the [label](#CompletionItem.label)\nis used."
+				},
+				{
+					"name": "insertText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A string that should be inserted into a document when selecting\nthis completion. When `falsy` the [label](#CompletionItem.label)\nis used.\n\nThe `insertText` is subject to interpretation by the client side.\nSome tools might not take the string literally. For example\nVS Code when code complete is requested in this example\n`con<cursor position>` and a completion item with an `insertText` of\n`console` is provided it will only insert `sole`. Therefore it is\nrecommended to use `textEdit` instead since it avoids additional client\nside interpretation."
+				},
+				{
+					"name": "insertTextFormat",
+					"type": {
+						"kind": "reference",
+						"name": "InsertTextFormat"
+					},
+					"optional": true,
+					"documentation": "The format of the insert text. The format applies to both the\n`insertText` property and the `newText` property of a provided\n`textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.\n\nPlease note that the insertTextFormat doesn't apply to\n`additionalTextEdits`."
+				},
+				{
+					"name": "insertTextMode",
+					"type": {
+						"kind": "reference",
+						"name": "InsertTextMode"
+					},
+					"optional": true,
+					"documentation": "How whitespace and indentation is handled during completion\nitem insertion. If not provided the clients default value depends on\nthe `textDocument.completion.insertTextMode` client capability.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "textEdit",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "TextEdit"
+							},
+							{
+								"kind": "reference",
+								"name": "InsertReplaceEdit"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "An [edit](#TextEdit) which is applied to a document when selecting\nthis completion. When an edit is provided the value of\n[insertText](#CompletionItem.insertText) is ignored.\n\nMost editors support two different operations when accepting a completion\nitem. One is to insert a completion text and the other is to replace an\nexisting text with a completion text. Since this can usually not be\npredetermined by a server it can report both ranges. Clients need to\nsignal support for `InsertReplaceEdits` via the\n`textDocument.completion.insertReplaceSupport` client capability\nproperty.\n\n*Note 1:* The text edit's range as well as both ranges from an insert\nreplace edit must be a [single line] and they must contain the position\nat which completion has been requested.\n*Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range\nmust be a prefix of the edit's replace range, that means it must be\ncontained and starting at the same position.\n\n@since 3.16.0 additional type `InsertReplaceEdit`",
+					"since": "3.16.0 additional type `InsertReplaceEdit`"
+				},
+				{
+					"name": "textEditText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The edit text used if the completion item is part of a CompletionList and\nCompletionList defines an item default for the text edit range.\n\nClients will only honor this property if they opt into completion list\nitem defaults using the capability `completionList.itemDefaults`.\n\nIf not provided and a list's default range is provided the label\nproperty is used as a text.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "additionalTextEdits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TextEdit"
+						}
+					},
+					"optional": true,
+					"documentation": "An optional array of additional [text edits](#TextEdit) that are applied when\nselecting this completion. Edits must not overlap (including the same insert position)\nwith the main [edit](#CompletionItem.textEdit) nor with themselves.\n\nAdditional text edits should be used to change text unrelated to the current cursor position\n(for example adding an import statement at the top of the file if the completion item will\ninsert an unqualified type)."
+				},
+				{
+					"name": "commitCharacters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "An optional set of characters that when pressed while this completion is active will accept it first and\nthen type that character. *Note* that all commit characters should have `length=1` and that superfluous\ncharacters will be ignored."
+				},
+				{
+					"name": "command",
+					"type": {
+						"kind": "reference",
+						"name": "Command"
+					},
+					"optional": true,
+					"documentation": "An optional [command](#Command) that is executed *after* inserting this completion. *Note* that\nadditional modifications to the current document should be described with the\n[additionalTextEdits](#CompletionItem.additionalTextEdits)-property."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on a completion item between a\n[CompletionRequest](#CompletionRequest) and a [CompletionResolveRequest](#CompletionResolveRequest)."
+				}
+			],
+			"documentation": "A completion item represents a text snippet that is\nproposed to complete text that is being typed."
+		},
+		{
+			"name": "CompletionList",
+			"properties": [
+				{
+					"name": "isIncomplete",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "This list it not complete. Further typing results in recomputing this list.\n\nRecomputed lists have all their items replaced (not appended) in the\nincomplete completion sessions."
+				},
+				{
+					"name": "itemDefaults",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "commitCharacters",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"optional": true,
+									"documentation": "A default commit character set.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								},
+								{
+									"name": "editRange",
+									"type": {
+										"kind": "or",
+										"items": [
+											{
+												"kind": "reference",
+												"name": "Range"
+											},
+											{
+												"kind": "literal",
+												"value": {
+													"properties": [
+														{
+															"name": "insert",
+															"type": {
+																"kind": "reference",
+																"name": "Range"
+															}
+														},
+														{
+															"name": "replace",
+															"type": {
+																"kind": "reference",
+																"name": "Range"
+															}
+														}
+													]
+												}
+											}
+										]
+									},
+									"optional": true,
+									"documentation": "A default edit range.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								},
+								{
+									"name": "insertTextFormat",
+									"type": {
+										"kind": "reference",
+										"name": "InsertTextFormat"
+									},
+									"optional": true,
+									"documentation": "A default insert text format.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								},
+								{
+									"name": "insertTextMode",
+									"type": {
+										"kind": "reference",
+										"name": "InsertTextMode"
+									},
+									"optional": true,
+									"documentation": "A default insert text mode.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								},
+								{
+									"name": "data",
+									"type": {
+										"kind": "reference",
+										"name": "LSPAny"
+									},
+									"optional": true,
+									"documentation": "A default data value.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "In many cases the items of an actual completion result share the same\nvalue for properties like `commitCharacters` or the range of a text\nedit. A completion list can therefore define item defaults which will\nbe used if a completion item itself doesn't specify the value.\n\nIf a completion list specifies a default value and a completion item\nalso specifies a corresponding value the one from the item is used.\n\nServers are only allowed to return default values if the client\nsignals support for this via the `completionList.itemDefaults`\ncapability.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "items",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CompletionItem"
+						}
+					},
+					"documentation": "The completion items."
+				}
+			],
+			"documentation": "Represents a collection of [completion items](#CompletionItem) to be presented\nin the editor."
+		},
+		{
+			"name": "CompletionRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "CompletionOptions"
+				}
+			],
+			"documentation": "Registration options for a [CompletionRequest](#CompletionRequest)."
+		},
+		{
+			"name": "HoverParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "Parameters for a [HoverRequest](#HoverRequest)."
+		},
+		{
+			"name": "Hover",
+			"properties": [
+				{
+					"name": "contents",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkedString"
+							},
+							{
+								"kind": "array",
+								"element": {
+									"kind": "reference",
+									"name": "MarkedString"
+								}
+							}
+						]
+					},
+					"documentation": "The hover's content"
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"optional": true,
+					"documentation": "An optional range inside the text document that is used to\nvisualize the hover, e.g. by changing the background color."
+				}
+			],
+			"documentation": "The result of a hover request."
+		},
+		{
+			"name": "HoverRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "HoverOptions"
+				}
+			],
+			"documentation": "Registration options for a [HoverRequest](#HoverRequest)."
+		},
+		{
+			"name": "SignatureHelpParams",
+			"properties": [
+				{
+					"name": "context",
+					"type": {
+						"kind": "reference",
+						"name": "SignatureHelpContext"
+					},
+					"optional": true,
+					"documentation": "The signature help context. This is only available if the client specifies\nto send this using the client capability `textDocument.signatureHelp.contextSupport === true`\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "Parameters for a [SignatureHelpRequest](#SignatureHelpRequest)."
+		},
+		{
+			"name": "SignatureHelp",
+			"properties": [
+				{
+					"name": "signatures",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SignatureInformation"
+						}
+					},
+					"documentation": "One or more signatures."
+				},
+				{
+					"name": "activeSignature",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The active signature. If omitted or the value lies outside the\nrange of `signatures` the value defaults to zero or is ignored if\nthe `SignatureHelp` has no signatures.\n\nWhenever possible implementors should make an active decision about\nthe active signature and shouldn't rely on a default value.\n\nIn future version of the protocol this property might become\nmandatory to better express this."
+				},
+				{
+					"name": "activeParameter",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The active parameter of the active signature. If omitted or the value\nlies outside the range of `signatures[activeSignature].parameters`\ndefaults to 0 if the active signature has parameters. If\nthe active signature has no parameters it is ignored.\nIn future version of the protocol this property might become\nmandatory to better express the active parameter if the\nactive signature does have any."
+				}
+			],
+			"documentation": "Signature help represents the signature of something\ncallable. There can be multiple signature but only one\nactive and only one active parameter."
+		},
+		{
+			"name": "SignatureHelpRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "SignatureHelpOptions"
+				}
+			],
+			"documentation": "Registration options for a [SignatureHelpRequest](#SignatureHelpRequest)."
+		},
+		{
+			"name": "DefinitionParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [DefinitionRequest](#DefinitionRequest)."
+		},
+		{
+			"name": "DefinitionRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DefinitionOptions"
+				}
+			],
+			"documentation": "Registration options for a [DefinitionRequest](#DefinitionRequest)."
+		},
+		{
+			"name": "ReferenceParams",
+			"properties": [
+				{
+					"name": "context",
+					"type": {
+						"kind": "reference",
+						"name": "ReferenceContext"
+					}
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [ReferencesRequest](#ReferencesRequest)."
+		},
+		{
+			"name": "ReferenceRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "ReferenceOptions"
+				}
+			],
+			"documentation": "Registration options for a [ReferencesRequest](#ReferencesRequest)."
+		},
+		{
+			"name": "DocumentHighlightParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [DocumentHighlightRequest](#DocumentHighlightRequest)."
+		},
+		{
+			"name": "DocumentHighlight",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range this highlight applies to."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentHighlightKind"
+					},
+					"optional": true,
+					"documentation": "The highlight kind, default is [text](#DocumentHighlightKind.Text)."
+				}
+			],
+			"documentation": "A document highlight is a range inside a text document which deserves\nspecial attention. Usually a document highlight is visualized by changing\nthe background color of its range."
+		},
+		{
+			"name": "DocumentHighlightRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentHighlightOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentHighlightRequest](#DocumentHighlightRequest)."
+		},
+		{
+			"name": "DocumentSymbolParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "Parameters for a [DocumentSymbolRequest](#DocumentSymbolRequest)."
+		},
+		{
+			"name": "SymbolInformation",
+			"properties": [
+				{
+					"name": "deprecated",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Indicates if this symbol is deprecated.\n\n@deprecated Use tags instead"
+				},
+				{
+					"name": "location",
+					"type": {
+						"kind": "reference",
+						"name": "Location"
+					},
+					"documentation": "The location of this symbol. The location's range is used by a tool\nto reveal the location in the editor. If the symbol is selected in the\ntool the range's start information is used to position the cursor. So\nthe range usually spans more than the actual symbol's name and does\nnormally include things like visibility modifiers.\n\nThe range doesn't have to denote a node range in the sense of an abstract\nsyntax tree. It can therefore not be used to re-construct a hierarchy of\nthe symbols."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "BaseSymbolInformation"
+				}
+			],
+			"documentation": "Represents information about programming constructs like variables, classes,\ninterfaces etc."
+		},
+		{
+			"name": "DocumentSymbol",
+			"properties": [
+				{
+					"name": "name",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of this symbol. Will be displayed in the user interface and therefore must not be\nan empty string or a string only consisting of white spaces."
+				},
+				{
+					"name": "detail",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "More detail for this symbol, e.g the signature of a function."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "SymbolKind"
+					},
+					"documentation": "The kind of this symbol."
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Tags for this document symbol.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "deprecated",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Indicates if this symbol is deprecated.\n\n@deprecated Use tags instead"
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range enclosing this symbol not including leading/trailing whitespace but everything else\nlike comments. This information is typically used to determine if the clients cursor is\ninside the symbol to reveal in the symbol in the UI."
+				},
+				{
+					"name": "selectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.\nMust be contained by the `range`."
+				},
+				{
+					"name": "children",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DocumentSymbol"
+						}
+					},
+					"optional": true,
+					"documentation": "Children of this symbol, e.g. properties of a class."
+				}
+			],
+			"documentation": "Represents programming constructs like variables, classes, interfaces etc.\nthat appear in a document. Document symbols can be hierarchical and they\nhave two ranges: one that encloses its definition and one that points to\nits most interesting range, e.g. the range of an identifier."
+		},
+		{
+			"name": "DocumentSymbolRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentSymbolOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentSymbolRequest](#DocumentSymbolRequest)."
+		},
+		{
+			"name": "CodeActionParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document in which the command was invoked."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range for which the command was invoked."
+				},
+				{
+					"name": "context",
+					"type": {
+						"kind": "reference",
+						"name": "CodeActionContext"
+					},
+					"documentation": "Context carrying additional information."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameters of a [CodeActionRequest](#CodeActionRequest)."
+		},
+		{
+			"name": "Command",
+			"properties": [
+				{
+					"name": "title",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "Title of the command, like `save`."
+				},
+				{
+					"name": "command",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The identifier of the actual command handler."
+				},
+				{
+					"name": "arguments",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "LSPAny"
+						}
+					},
+					"optional": true,
+					"documentation": "Arguments that the command handler should be\ninvoked with."
+				}
+			],
+			"documentation": "Represents a reference to a command. Provides a title which\nwill be used to represent a command in the UI and, optionally,\nan array of arguments which will be passed to the command handler\nfunction when invoked."
+		},
+		{
+			"name": "CodeAction",
+			"properties": [
+				{
+					"name": "title",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A short, human-readable, title for this code action."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "CodeActionKind"
+					},
+					"optional": true,
+					"documentation": "The kind of the code action.\n\nUsed to filter code actions."
+				},
+				{
+					"name": "diagnostics",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Diagnostic"
+						}
+					},
+					"optional": true,
+					"documentation": "The diagnostics that this code action resolves."
+				},
+				{
+					"name": "isPreferred",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted\nby keybindings.\n\nA quick fix should be marked preferred if it properly addresses the underlying error.\nA refactoring should be marked preferred if it is the most reasonable choice of actions to take.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "disabled",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "reason",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "Human readable description of why the code action is currently disabled.\n\nThis is displayed in the code actions UI."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Marks that the code action cannot currently be applied.\n\nClients should follow the following guidelines regarding disabled code actions:\n\n  - Disabled code actions are not shown in automatic [lightbulbs](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)\n    code action menus.\n\n  - Disabled actions are shown as faded out in the code action menu when the user requests a more specific type\n    of code action, such as refactorings.\n\n  - If the user has a [keybinding](https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions)\n    that auto applies a code action and only disabled code actions are returned, the client should show the user an\n    error message with `reason` in the editor.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "edit",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					"optional": true,
+					"documentation": "The workspace edit this code action performs."
+				},
+				{
+					"name": "command",
+					"type": {
+						"kind": "reference",
+						"name": "Command"
+					},
+					"optional": true,
+					"documentation": "A command this code action executes. If a code action\nprovides an edit and a command, first the edit is\nexecuted and then the command."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on a code action between\na `textDocument/codeAction` and a `codeAction/resolve` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "A code action represents a change that can be performed in code, e.g. to fix a problem or\nto refactor code.\n\nA CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed."
+		},
+		{
+			"name": "CodeActionRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "CodeActionOptions"
+				}
+			],
+			"documentation": "Registration options for a [CodeActionRequest](#CodeActionRequest)."
+		},
+		{
+			"name": "WorkspaceSymbolParams",
+			"properties": [
+				{
+					"name": "query",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A query string to filter symbols by. Clients may send an empty\nstring here to request all symbols."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameters of a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest)."
+		},
+		{
+			"name": "WorkspaceSymbol",
+			"properties": [
+				{
+					"name": "location",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "Location"
+							},
+							{
+								"kind": "literal",
+								"value": {
+									"properties": [
+										{
+											"name": "uri",
+											"type": {
+												"kind": "base",
+												"name": "DocumentUri"
+											}
+										}
+									]
+								}
+							}
+						]
+					},
+					"documentation": "The location of the symbol. Whether a server is allowed to\nreturn a location without a range depends on the client\ncapability `workspace.symbol.resolveSupport`.\n\nSee SymbolInformation#location for more details."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on a workspace symbol between a\nworkspace symbol request and a workspace symbol resolve request."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "BaseSymbolInformation"
+				}
+			],
+			"documentation": "A special workspace symbol that supports locations without a range.\n\nSee also SymbolInformation.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceSymbolRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "WorkspaceSymbolOptions"
+				}
+			],
+			"documentation": "Registration options for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest)."
+		},
+		{
+			"name": "CodeLensParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to request code lens for."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameters of a [CodeLensRequest](#CodeLensRequest)."
+		},
+		{
+			"name": "CodeLens",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range in which this code lens is valid. Should only span a single line."
+				},
+				{
+					"name": "command",
+					"type": {
+						"kind": "reference",
+						"name": "Command"
+					},
+					"optional": true,
+					"documentation": "The command this code lens represents."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on a code lens item between\na [CodeLensRequest](#CodeLensRequest) and a [CodeLensResolveRequest]\n(#CodeLensResolveRequest)"
+				}
+			],
+			"documentation": "A code lens represents a [command](#Command) that should be shown along with\nsource text, like the number of references, a way to run tests, etc.\n\nA code lens is _unresolved_ when no command is associated to it. For performance\nreasons the creation of a code lens and resolving should be done in two stages."
+		},
+		{
+			"name": "CodeLensRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "CodeLensOptions"
+				}
+			],
+			"documentation": "Registration options for a [CodeLensRequest](#CodeLensRequest)."
+		},
+		{
+			"name": "DocumentLinkParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to provide document links for."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				},
+				{
+					"kind": "reference",
+					"name": "PartialResultParams"
+				}
+			],
+			"documentation": "The parameters of a [DocumentLinkRequest](#DocumentLinkRequest)."
+		},
+		{
+			"name": "DocumentLink",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range this link applies to."
+				},
+				{
+					"name": "target",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The uri this link points to. If missing a resolve request is sent later."
+				},
+				{
+					"name": "tooltip",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The tooltip text when you hover over this link.\n\nIf a tooltip is provided, is will be displayed in a string that includes instructions on how to\ntrigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,\nuser settings, and localization.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved on a document link between a\nDocumentLinkRequest and a DocumentLinkResolveRequest."
+				}
+			],
+			"documentation": "A document link is a range in a text document that links to an internal or external resource, like another\ntext document or a web site."
+		},
+		{
+			"name": "DocumentLinkRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentLinkOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentLinkRequest](#DocumentLinkRequest)."
+		},
+		{
+			"name": "DocumentFormattingParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to format."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "FormattingOptions"
+					},
+					"documentation": "The format options."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameters of a [DocumentFormattingRequest](#DocumentFormattingRequest)."
+		},
+		{
+			"name": "DocumentFormattingRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentFormattingOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentFormattingRequest](#DocumentFormattingRequest)."
+		},
+		{
+			"name": "DocumentRangeFormattingParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to format."
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range to format"
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "FormattingOptions"
+					},
+					"documentation": "The format options"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameters of a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest)."
+		},
+		{
+			"name": "DocumentRangeFormattingRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentRangeFormattingOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest)."
+		},
+		{
+			"name": "DocumentOnTypeFormattingParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to format."
+				},
+				{
+					"name": "position",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The position around which the on type formatting should happen.\nThis is not necessarily the exact position where the character denoted\nby the property `ch` got typed."
+				},
+				{
+					"name": "ch",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The character that has been typed that triggered the formatting\non type request. That is not necessarily the last character that\ngot inserted into the document since the client could auto insert\ncharacters as well (e.g. like automatic brace completion)."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "FormattingOptions"
+					},
+					"documentation": "The formatting options."
+				}
+			],
+			"documentation": "The parameters of a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest)."
+		},
+		{
+			"name": "DocumentOnTypeFormattingRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "DocumentOnTypeFormattingOptions"
+				}
+			],
+			"documentation": "Registration options for a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest)."
+		},
+		{
+			"name": "RenameParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The document to rename."
+				},
+				{
+					"name": "position",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The position at which this request was sent."
+				},
+				{
+					"name": "newName",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The new name of the symbol. If the given name is not valid the\nrequest must return a [ResponseError](#ResponseError) with an\nappropriate message set."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameters of a [RenameRequest](#RenameRequest)."
+		},
+		{
+			"name": "RenameRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentRegistrationOptions"
+				},
+				{
+					"kind": "reference",
+					"name": "RenameOptions"
+				}
+			],
+			"documentation": "Registration options for a [RenameRequest](#RenameRequest)."
+		},
+		{
+			"name": "PrepareRenameParams",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentPositionParams"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			]
+		},
+		{
+			"name": "ExecuteCommandParams",
+			"properties": [
+				{
+					"name": "command",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The identifier of the actual command handler."
+				},
+				{
+					"name": "arguments",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "LSPAny"
+						}
+					},
+					"optional": true,
+					"documentation": "Arguments that the command should be invoked with."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The parameters of a [ExecuteCommandRequest](#ExecuteCommandRequest)."
+		},
+		{
+			"name": "ExecuteCommandRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "ExecuteCommandOptions"
+				}
+			],
+			"documentation": "Registration options for a [ExecuteCommandRequest](#ExecuteCommandRequest)."
+		},
+		{
+			"name": "ApplyWorkspaceEditParams",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional label of the workspace edit. This label is\npresented in the user interface for example on an undo\nstack to undo the workspace edit."
+				},
+				{
+					"name": "edit",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceEdit"
+					},
+					"documentation": "The edits to apply."
+				}
+			],
+			"documentation": "The parameters passed via a apply workspace edit request."
+		},
+		{
+			"name": "ApplyWorkspaceEditResult",
+			"properties": [
+				{
+					"name": "applied",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "Indicates whether the edit was applied or not."
+				},
+				{
+					"name": "failureReason",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional textual description for why the edit was not applied.\nThis may be used by the server for diagnostic logging or to provide\na suitable error for a request that triggered the edit."
+				},
+				{
+					"name": "failedChange",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "Depending on the client's failure handling strategy `failedChange` might\ncontain the index of the change that failed. This property is only available\nif the client signals a `failureHandlingStrategy` in its client capabilities."
+				}
+			],
+			"documentation": "The result returned from the apply workspace edit request.\n\n@since 3.17 renamed from ApplyWorkspaceEditResponse",
+			"since": "3.17 renamed from ApplyWorkspaceEditResponse"
+		},
+		{
+			"name": "WorkDoneProgressBegin",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "begin"
+					}
+				},
+				{
+					"name": "title",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "Mandatory title of the progress operation. Used to briefly inform about\nthe kind of operation being performed.\n\nExamples: \"Indexing\" or \"Linking dependencies\"."
+				},
+				{
+					"name": "cancellable",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Controls if a cancel button should show to allow the user to cancel the\nlong running operation. Clients that don't support cancellation are allowed\nto ignore the setting."
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "Optional, more detailed associated progress message. Contains\ncomplementary information to the `title`.\n\nExamples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\nIf unset, the previous progress message (if any) is still valid."
+				},
+				{
+					"name": "percentage",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "Optional progress percentage to display (value 100 is considered 100%).\nIf not provided infinite progress is assumed and clients are allowed\nto ignore the `percentage` value in subsequent in report notifications.\n\nThe value should be steadily rising. Clients are free to ignore values\nthat are not following this rule. The value range is [0, 100]."
+				}
+			]
+		},
+		{
+			"name": "WorkDoneProgressReport",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "report"
+					}
+				},
+				{
+					"name": "cancellable",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Controls enablement state of a cancel button.\n\nClients that don't support cancellation or don't support controlling the button's\nenablement state are allowed to ignore the property."
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "Optional, more detailed associated progress message. Contains\ncomplementary information to the `title`.\n\nExamples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\nIf unset, the previous progress message (if any) is still valid."
+				},
+				{
+					"name": "percentage",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "Optional progress percentage to display (value 100 is considered 100%).\nIf not provided infinite progress is assumed and clients are allowed\nto ignore the `percentage` value in subsequent in report notifications.\n\nThe value should be steadily rising. Clients are free to ignore values\nthat are not following this rule. The value range is [0, 100]"
+				}
+			]
+		},
+		{
+			"name": "WorkDoneProgressEnd",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "end"
+					}
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "Optional, a final message indicating to for example indicate the outcome\nof the operation."
+				}
+			]
+		},
+		{
+			"name": "SetTraceParams",
+			"properties": [
+				{
+					"name": "value",
+					"type": {
+						"kind": "reference",
+						"name": "TraceValues"
+					}
+				}
+			]
+		},
+		{
+			"name": "LogTraceParams",
+			"properties": [
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					}
+				},
+				{
+					"name": "verbose",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true
+				}
+			]
+		},
+		{
+			"name": "CancelParams",
+			"properties": [
+				{
+					"name": "id",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "string"
+							}
+						]
+					},
+					"documentation": "The request id to cancel."
+				}
+			]
+		},
+		{
+			"name": "ProgressParams",
+			"properties": [
+				{
+					"name": "token",
+					"type": {
+						"kind": "reference",
+						"name": "ProgressToken"
+					},
+					"documentation": "The progress token provided by the client or server."
+				},
+				{
+					"name": "value",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"documentation": "The progress data."
+				}
+			]
+		},
+		{
+			"name": "TextDocumentPositionParams",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentIdentifier"
+					},
+					"documentation": "The text document."
+				},
+				{
+					"name": "position",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The position inside the text document."
+				}
+			],
+			"documentation": "A parameter literal used in requests to pass a text document and a position inside that\ndocument."
+		},
+		{
+			"name": "WorkDoneProgressParams",
+			"properties": [
+				{
+					"name": "workDoneToken",
+					"type": {
+						"kind": "reference",
+						"name": "ProgressToken"
+					},
+					"optional": true,
+					"documentation": "An optional token that a server can use to report work done progress."
+				}
+			]
+		},
+		{
+			"name": "LocationLink",
+			"properties": [
+				{
+					"name": "originSelectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"optional": true,
+					"documentation": "Span of the origin of this link.\n\nUsed as the underlined span for mouse interaction. Defaults to the word range at\nthe definition position."
+				},
+				{
+					"name": "targetUri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The target resource identifier of this link."
+				},
+				{
+					"name": "targetRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The full target range of this link. If the target for example is a symbol then target range is the\nrange enclosing this symbol not including leading/trailing whitespace but everything else\nlike comments. This information is typically used to highlight the range in the editor."
+				},
+				{
+					"name": "targetSelectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range that should be selected and revealed when this link is being followed, e.g the name of a function.\nMust be contained by the `targetRange`. See also `DocumentSymbol#range`"
+				}
+			],
+			"documentation": "Represents the connection of two locations. Provides additional metadata over normal [locations](#Location),\nincluding an origin range."
+		},
+		{
+			"name": "Range",
+			"properties": [
+				{
+					"name": "start",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The range's start position."
+				},
+				{
+					"name": "end",
+					"type": {
+						"kind": "reference",
+						"name": "Position"
+					},
+					"documentation": "The range's end position."
+				}
+			],
+			"documentation": "A range in a text document expressed as (zero-based) start and end positions.\n\nIf you want to specify a range that contains a line including the line ending\ncharacter(s) then use an end position denoting the start of the next line.\nFor example:\n```ts\n{\n    start: { line: 5, character: 23 }\n    end : { line 6, character : 0 }\n}\n```"
+		},
+		{
+			"name": "ImplementationOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "StaticRegistrationOptions",
+			"properties": [
+				{
+					"name": "id",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The id used to register the request. The id can be used to deregister\nthe request again. See also Registration#id."
+				}
+			],
+			"documentation": "Static registration options to be returned in the initialize\nrequest."
+		},
+		{
+			"name": "TypeDefinitionOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "WorkspaceFoldersChangeEvent",
+			"properties": [
+				{
+					"name": "added",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceFolder"
+						}
+					},
+					"documentation": "The array of added workspace folders"
+				},
+				{
+					"name": "removed",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "WorkspaceFolder"
+						}
+					},
+					"documentation": "The array of the removed workspace folders"
+				}
+			],
+			"documentation": "The workspace folder change event."
+		},
+		{
+			"name": "ConfigurationItem",
+			"properties": [
+				{
+					"name": "scopeUri",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The scope to get the configuration section for."
+				},
+				{
+					"name": "section",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The configuration section asked for."
+				}
+			]
+		},
+		{
+			"name": "TextDocumentIdentifier",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The text document's uri."
+				}
+			],
+			"documentation": "A literal to identify a text document in the client."
+		},
+		{
+			"name": "Color",
+			"properties": [
+				{
+					"name": "red",
+					"type": {
+						"kind": "base",
+						"name": "decimal"
+					},
+					"documentation": "The red component of this color in the range [0-1]."
+				},
+				{
+					"name": "green",
+					"type": {
+						"kind": "base",
+						"name": "decimal"
+					},
+					"documentation": "The green component of this color in the range [0-1]."
+				},
+				{
+					"name": "blue",
+					"type": {
+						"kind": "base",
+						"name": "decimal"
+					},
+					"documentation": "The blue component of this color in the range [0-1]."
+				},
+				{
+					"name": "alpha",
+					"type": {
+						"kind": "base",
+						"name": "decimal"
+					},
+					"documentation": "The alpha component of this color in the range [0-1]."
+				}
+			],
+			"documentation": "Represents a color in RGBA space."
+		},
+		{
+			"name": "DocumentColorOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "FoldingRangeOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "DeclarationOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "Position",
+			"properties": [
+				{
+					"name": "line",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "Line position in a document (zero-based).\n\nIf a line number is greater than the number of lines in a document, it defaults back to the number of lines in the document.\nIf a line number is negative, it defaults to 0."
+				},
+				{
+					"name": "character",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "Character offset on a line in a document (zero-based).\n\nThe meaning of this offset is determined by the negotiated\n`PositionEncodingKind`.\n\nIf the character value is greater than the line length it defaults back to the\nline length."
+				}
+			],
+			"documentation": "Position in a text document expressed as zero-based line and character\noffset. Prior to 3.17 the offsets were always based on a UTF-16 string\nrepresentation. So a string of the form `a𐐀b` the character offset of the\ncharacter `a` is 0, the character offset of `𐐀` is 1 and the character\noffset of b is 3 since `𐐀` is represented using two code units in UTF-16.\nSince 3.17 clients and servers can agree on a different string encoding\nrepresentation (e.g. UTF-8). The client announces it's supported encoding\nvia the client capability [`general.positionEncodings`](#clientCapabilities).\nThe value is an array of position encodings the client supports, with\ndecreasing preference (e.g. the encoding at index `0` is the most preferred\none). To stay backwards compatible the only mandatory encoding is UTF-16\nrepresented via the string `utf-16`. The server can pick one of the\nencodings offered by the client and signals that encoding back to the\nclient via the initialize result's property\n[`capabilities.positionEncoding`](#serverCapabilities). If the string value\n`utf-16` is missing from the client's capability `general.positionEncodings`\nservers can safely assume that the client supports UTF-16. If the server\nomits the position encoding in its initialize result the encoding defaults\nto the string value `utf-16`. Implementation considerations: since the\nconversion from one encoding into another requires the content of the\nfile / line the conversion is best done where the file is read which is\nusually on the server side.\n\nPositions are line end character agnostic. So you can not specify a position\nthat denotes `\\r|\\n` or `\\n|` where `|` represents the character offset.\n\n@since 3.17.0 - support for negotiated position encoding.",
+			"since": "3.17.0 - support for negotiated position encoding."
+		},
+		{
+			"name": "SelectionRangeOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "CallHierarchyOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Call hierarchy options used during static registration.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensOptions",
+			"properties": [
+				{
+					"name": "legend",
+					"type": {
+						"kind": "reference",
+						"name": "SemanticTokensLegend"
+					},
+					"documentation": "The legend used by the server"
+				},
+				{
+					"name": "range",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "literal",
+								"value": {
+									"properties": []
+								}
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "Server supports providing semantic tokens for a specific range\nof a document."
+				},
+				{
+					"name": "full",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "literal",
+								"value": {
+									"properties": [
+										{
+											"name": "delta",
+											"type": {
+												"kind": "base",
+												"name": "boolean"
+											},
+											"optional": true,
+											"documentation": "The server supports deltas for full documents."
+										}
+									]
+								}
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "Server supports providing semantic tokens for a full document."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensEdit",
+			"properties": [
+				{
+					"name": "start",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The start offset of the edit."
+				},
+				{
+					"name": "deleteCount",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The count of elements to remove."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "uinteger"
+						}
+					},
+					"optional": true,
+					"documentation": "The elements to insert."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "LinkedEditingRangeOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "FileCreate",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A file:// URI for the location of the file/folder being created."
+				}
+			],
+			"documentation": "Represents information on a file/folder create.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "TextDocumentEdit",
+			"properties": [
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "OptionalVersionedTextDocumentIdentifier"
+					},
+					"documentation": "The text document to change."
+				},
+				{
+					"name": "edits",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "TextEdit"
+								},
+								{
+									"kind": "reference",
+									"name": "AnnotatedTextEdit"
+								}
+							]
+						}
+					},
+					"documentation": "The edits to be applied.\n\n@since 3.16.0 - support for AnnotatedTextEdit. This is guarded using a\nclient capability.",
+					"since": "3.16.0 - support for AnnotatedTextEdit. This is guarded using a\nclient capability."
+				}
+			],
+			"documentation": "Describes textual changes on a text document. A TextDocumentEdit describes all changes\non a document version Si and after they are applied move the document to version Si+1.\nSo the creator of a TextDocumentEdit doesn't need to sort the array of edits or do any\nkind of ordering. However the edits must be non overlapping."
+		},
+		{
+			"name": "CreateFile",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "create"
+					},
+					"documentation": "A create"
+				},
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The resource to create."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "CreateFileOptions"
+					},
+					"optional": true,
+					"documentation": "Additional options"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "ResourceOperation"
+				}
+			],
+			"documentation": "Create file operation."
+		},
+		{
+			"name": "RenameFile",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "rename"
+					},
+					"documentation": "A rename"
+				},
+				{
+					"name": "oldUri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The old (existing) location."
+				},
+				{
+					"name": "newUri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The new location."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "RenameFileOptions"
+					},
+					"optional": true,
+					"documentation": "Rename options."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "ResourceOperation"
+				}
+			],
+			"documentation": "Rename file operation"
+		},
+		{
+			"name": "DeleteFile",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "delete"
+					},
+					"documentation": "A delete"
+				},
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The file to delete."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "DeleteFileOptions"
+					},
+					"optional": true,
+					"documentation": "Delete options."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "ResourceOperation"
+				}
+			],
+			"documentation": "Delete file operation"
+		},
+		{
+			"name": "ChangeAnnotation",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A human-readable string describing the actual change. The string\nis rendered prominent in the user interface."
+				},
+				{
+					"name": "needsConfirmation",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "A flag which indicates that user confirmation is needed\nbefore applying the change."
+				},
+				{
+					"name": "description",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A human-readable string which is rendered less prominent in\nthe user interface."
+				}
+			],
+			"documentation": "Additional information that describes document changes.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "FileOperationFilter",
+			"properties": [
+				{
+					"name": "scheme",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A Uri scheme like `file` or `untitled`."
+				},
+				{
+					"name": "pattern",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationPattern"
+					},
+					"documentation": "The actual file operation pattern."
+				}
+			],
+			"documentation": "A filter to describe in which file operation requests or notifications\nthe server is interested in receiving.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "FileRename",
+			"properties": [
+				{
+					"name": "oldUri",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A file:// URI for the original location of the file/folder being renamed."
+				},
+				{
+					"name": "newUri",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A file:// URI for the new location of the file/folder being renamed."
+				}
+			],
+			"documentation": "Represents information on a file/folder rename.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "FileDelete",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A file:// URI for the location of the file/folder being deleted."
+				}
+			],
+			"documentation": "Represents information on a file/folder delete.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MonikerOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			]
+		},
+		{
+			"name": "TypeHierarchyOptions",
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"properties": [],
+			"documentation": "Type hierarchy options used during static registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueContext",
+			"properties": [
+				{
+					"name": "frameId",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"documentation": "The stack frame (as a DAP Id) where the execution has stopped."
+				},
+				{
+					"name": "stoppedLocation",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range where execution has stopped.\nTypically the end position of the range denotes the line where the inline values are shown."
+				}
+			],
+			"documentation": "@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueText",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range for which the inline value applies."
+				},
+				{
+					"name": "text",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The text of the inline value."
+				}
+			],
+			"documentation": "Provide inline value as text.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueVariableLookup",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range for which the inline value applies.\nThe range is used to extract the variable name from the underlying document."
+				},
+				{
+					"name": "variableName",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "If specified the name of the variable to look up."
+				},
+				{
+					"name": "caseSensitiveLookup",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "How to perform the lookup."
+				}
+			],
+			"documentation": "Provide inline value through a variable lookup.\nIf only a range is specified, the variable name will be extracted from the underlying document.\nAn optional variable name can be used to override the extracted name.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueEvaluatableExpression",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The document range for which the inline value applies.\nThe range is used to extract the evaluatable expression from the underlying document."
+				},
+				{
+					"name": "expression",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "If specified the expression overrides the extracted expression."
+				}
+			],
+			"documentation": "Provide an inline value through an expression evaluation.\nIf only a range is specified, the expression will be extracted from the underlying document.\nAn optional expression can be used to override the extracted expression.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueOptions",
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"properties": [],
+			"documentation": "Inline value options used during static registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHintLabelPart",
+			"properties": [
+				{
+					"name": "value",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The value of this label part."
+				},
+				{
+					"name": "tooltip",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The tooltip text when you hover over this label part. Depending on\nthe client capability `inlayHint.resolveSupport` clients might resolve\nthis property late using the resolve request."
+				},
+				{
+					"name": "location",
+					"type": {
+						"kind": "reference",
+						"name": "Location"
+					},
+					"optional": true,
+					"documentation": "An optional source code location that represents this\nlabel part.\n\nThe editor will use this location for the hover and for code navigation\nfeatures: This part will become a clickable link that resolves to the\ndefinition of the symbol at the given location (not necessarily the\nlocation itself), it shows the hover that shows at the given location,\nand it shows a context menu with further code navigation commands.\n\nDepending on the client capability `inlayHint.resolveSupport` clients\nmight resolve this property late using the resolve request."
+				},
+				{
+					"name": "command",
+					"type": {
+						"kind": "reference",
+						"name": "Command"
+					},
+					"optional": true,
+					"documentation": "An optional command for this label part.\n\nDepending on the client capability `inlayHint.resolveSupport` clients\nmight resolve this property late using the resolve request."
+				}
+			],
+			"documentation": "An inlay hint label part allows for interactive and composite labels\nof inlay hints.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "MarkupContent",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "MarkupKind"
+					},
+					"documentation": "The type of the Markup"
+				},
+				{
+					"name": "value",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The content itself"
+				}
+			],
+			"documentation": "A `MarkupContent` literal represents a string value which content is interpreted base on its\nkind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.\n\nIf the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.\nSee https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting\n\nHere is an example how such a string can be constructed using JavaScript / TypeScript:\n```ts\nlet markdown: MarkdownContent = {\n kind: MarkupKind.Markdown,\n value: [\n   '# Header',\n   'Some text',\n   '```typescript',\n   'someCode();',\n   '```'\n ].join('\\n')\n};\n```\n\n*Please Note* that clients might sanitize the return markdown. A client could decide to\nremove HTML from the markdown to avoid script execution."
+		},
+		{
+			"name": "InlayHintOptions",
+			"properties": [
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The server provides support to resolve additional\ninformation for an inlay hint item."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Inlay hint options used during static registration.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "RelatedFullDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "relatedDocuments",
+					"type": {
+						"kind": "map",
+						"key": {
+							"kind": "base",
+							"name": "DocumentUri"
+						},
+						"value": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "FullDocumentDiagnosticReport"
+								},
+								{
+									"kind": "reference",
+									"name": "UnchangedDocumentDiagnosticReport"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Diagnostics of related documents. This information is useful\nin programming languages where code in a file A can generate\ndiagnostics in a file B which A depends on. An example of\nsuch a language is C/C++ where marco definitions in a file\na.cpp and result in errors in a header file b.hpp.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "FullDocumentDiagnosticReport"
+				}
+			],
+			"documentation": "A full diagnostic report with a set of related documents.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "RelatedUnchangedDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "relatedDocuments",
+					"type": {
+						"kind": "map",
+						"key": {
+							"kind": "base",
+							"name": "DocumentUri"
+						},
+						"value": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "reference",
+									"name": "FullDocumentDiagnosticReport"
+								},
+								{
+									"kind": "reference",
+									"name": "UnchangedDocumentDiagnosticReport"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Diagnostics of related documents. This information is useful\nin programming languages where code in a file A can generate\ndiagnostics in a file B which A depends on. An example of\nsuch a language is C/C++ where marco definitions in a file\na.cpp and result in errors in a header file b.hpp.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "UnchangedDocumentDiagnosticReport"
+				}
+			],
+			"documentation": "An unchanged diagnostic report with a set of related documents.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "FullDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "full"
+					},
+					"documentation": "A full document diagnostic report."
+				},
+				{
+					"name": "resultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional result id. If provided it will\nbe sent on the next diagnostic request for the\nsame document."
+				},
+				{
+					"name": "items",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Diagnostic"
+						}
+					},
+					"documentation": "The actual items."
+				}
+			],
+			"documentation": "A diagnostic report with a full set of problems.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "UnchangedDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "stringLiteral",
+						"value": "unchanged"
+					},
+					"documentation": "A document diagnostic report indicating\nno changes to the last result. A server can\nonly return `unchanged` if result ids are\nprovided."
+				},
+				{
+					"name": "resultId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A result id which will be sent on the next\ndiagnostic request for the same document."
+				}
+			],
+			"documentation": "A diagnostic report indicating that the last returned\nreport is still accurate.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DiagnosticOptions",
+			"properties": [
+				{
+					"name": "identifier",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional identifier under which the diagnostics are\nmanaged by the client."
+				},
+				{
+					"name": "interFileDependencies",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "Whether the language has inter file dependencies meaning that\nediting code in one file can result in a different diagnostic\nset in another file. Inter file dependencies are common for\nmost programming languages and typically uncommon for linters."
+				},
+				{
+					"name": "workspaceDiagnostics",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "The server provides support for workspace diagnostics as well."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Diagnostic options.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "PreviousResultId",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The URI for which the client knowns a\nresult id."
+				},
+				{
+					"name": "value",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The value of the previous result id."
+				}
+			],
+			"documentation": "A previous result id in a workspace pull request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocument",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "The notebook document's uri."
+				},
+				{
+					"name": "notebookType",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The type of the notebook."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"documentation": "The version number of this document (it will increase after each\nchange, including undo/redo)."
+				},
+				{
+					"name": "metadata",
+					"type": {
+						"kind": "reference",
+						"name": "LSPObject"
+					},
+					"optional": true,
+					"documentation": "Additional metadata stored with the notebook\ndocument.\n\nNote: should always be an object literal (e.g. LSPObject)"
+				},
+				{
+					"name": "cells",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "NotebookCell"
+						}
+					},
+					"documentation": "The cells of a notebook."
+				}
+			],
+			"documentation": "A notebook document.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TextDocumentItem",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The text document's uri."
+				},
+				{
+					"name": "languageId",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The text document's language identifier."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"documentation": "The version number of this document (it will increase after each\nchange, including undo/redo)."
+				},
+				{
+					"name": "text",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The content of the opened text document."
+				}
+			],
+			"documentation": "An item to transfer a text document from the client to the\nserver."
+		},
+		{
+			"name": "VersionedNotebookDocumentIdentifier",
+			"properties": [
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"documentation": "The version number of this notebook document."
+				},
+				{
+					"name": "uri",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "The notebook document's uri."
+				}
+			],
+			"documentation": "A versioned notebook document identifier.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocumentChangeEvent",
+			"properties": [
+				{
+					"name": "metadata",
+					"type": {
+						"kind": "reference",
+						"name": "LSPObject"
+					},
+					"optional": true,
+					"documentation": "The changed meta data if any.\n\nNote: should always be an object literal (e.g. LSPObject)"
+				},
+				{
+					"name": "cells",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "structure",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "array",
+													"type": {
+														"kind": "reference",
+														"name": "NotebookCellArrayChange"
+													},
+													"documentation": "The change to the cell array."
+												},
+												{
+													"name": "didOpen",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "reference",
+															"name": "TextDocumentItem"
+														}
+													},
+													"optional": true,
+													"documentation": "Additional opened cell text documents."
+												},
+												{
+													"name": "didClose",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "reference",
+															"name": "TextDocumentIdentifier"
+														}
+													},
+													"optional": true,
+													"documentation": "Additional closed cell text documents."
+												}
+											]
+										}
+									},
+									"optional": true,
+									"documentation": "Changes to the cell structure to add or\nremove cells."
+								},
+								{
+									"name": "data",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "NotebookCell"
+										}
+									},
+									"optional": true,
+									"documentation": "Changes to notebook cells properties like its\nkind, execution summary or metadata."
+								},
+								{
+									"name": "textContent",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "literal",
+											"value": {
+												"properties": [
+													{
+														"name": "document",
+														"type": {
+															"kind": "reference",
+															"name": "VersionedTextDocumentIdentifier"
+														}
+													},
+													{
+														"name": "changes",
+														"type": {
+															"kind": "array",
+															"element": {
+																"kind": "reference",
+																"name": "TextDocumentContentChangeEvent"
+															}
+														}
+													}
+												]
+											}
+										}
+									},
+									"optional": true,
+									"documentation": "Changes to the text content of notebook cells."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Changes to cells"
+				}
+			],
+			"documentation": "A change event for a notebook document.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocumentIdentifier",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "The notebook document's uri."
+				}
+			],
+			"documentation": "A literal to identify a notebook document in the client.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "Registration",
+			"properties": [
+				{
+					"name": "id",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The id used to register the request. The id can be used to deregister\nthe request again."
+				},
+				{
+					"name": "method",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The method / capability to register for."
+				},
+				{
+					"name": "registerOptions",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "Options necessary for the registration."
+				}
+			],
+			"documentation": "General parameters to to register for an notification or to register a provider."
+		},
+		{
+			"name": "Unregistration",
+			"properties": [
+				{
+					"name": "id",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The id used to unregister the request or notification. Usually an id\nprovided during the register request."
+				},
+				{
+					"name": "method",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The method to unregister for."
+				}
+			],
+			"documentation": "General parameters to unregister a request or notification."
+		},
+		{
+			"name": "_InitializeParams",
+			"properties": [
+				{
+					"name": "processId",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "The process Id of the parent process that started\nthe server.\n\nIs `null` if the process has not been started by another process.\nIf the parent process is not alive then the server should exit."
+				},
+				{
+					"name": "clientInfo",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "name",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "The name of the client as defined by the client."
+								},
+								{
+									"name": "version",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "The client's version as defined by the client."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Information about the client\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "locale",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The locale the client is currently showing the user interface\nin. This must not necessarily be the locale of the operating\nsystem.\n\nUses IETF language tags as the value's syntax\n(See https://en.wikipedia.org/wiki/IETF_language_tag)\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "rootPath",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The rootPath of the workspace. Is null\nif no folder is open.\n\n@deprecated in favour of rootUri."
+				},
+				{
+					"name": "rootUri",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "DocumentUri"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "The rootUri of the workspace. Is null if no\nfolder is open. If both `rootPath` and `rootUri` are set\n`rootUri` wins.\n\n@deprecated in favour of workspaceFolders."
+				},
+				{
+					"name": "capabilities",
+					"type": {
+						"kind": "reference",
+						"name": "ClientCapabilities"
+					},
+					"documentation": "The capabilities provided by the client (editor or tool)"
+				},
+				{
+					"name": "initializationOptions",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "User provided initialization options."
+				},
+				{
+					"name": "trace",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "stringLiteral",
+								"value": "off"
+							},
+							{
+								"kind": "stringLiteral",
+								"value": "messages"
+							},
+							{
+								"kind": "stringLiteral",
+								"value": "compact"
+							},
+							{
+								"kind": "stringLiteral",
+								"value": "verbose"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The initial trace setting. If omitted trace is disabled ('off')."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressParams"
+				}
+			],
+			"documentation": "The initialize parameters"
+		},
+		{
+			"name": "WorkspaceFoldersInitializeParams",
+			"properties": [
+				{
+					"name": "workspaceFolders",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "array",
+								"element": {
+									"kind": "reference",
+									"name": "WorkspaceFolder"
+								}
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The workspace folders configured in the client when the server starts.\n\nThis property is only available if the client supports workspace folders.\nIt can be `null` if the client supports workspace folders but none are\nconfigured.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				}
+			]
+		},
+		{
+			"name": "ServerCapabilities",
+			"properties": [
+				{
+					"name": "positionEncoding",
+					"type": {
+						"kind": "reference",
+						"name": "PositionEncodingKind"
+					},
+					"optional": true,
+					"documentation": "The position encoding the server picked from the encodings offered\nby the client via the client capability `general.positionEncodings`.\n\nIf the client didn't provide any position encodings the only valid\nvalue that a server can return is 'utf-16'.\n\nIf omitted it defaults to 'utf-16'.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "textDocumentSync",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "TextDocumentSyncOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "TextDocumentSyncKind"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "Defines how text documents are synced. Is either a detailed structure\ndefining each notification or for backwards compatibility the\nTextDocumentSyncKind number."
+				},
+				{
+					"name": "notebookDocumentSync",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "NotebookDocumentSyncOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "NotebookDocumentSyncRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "Defines how notebook documents are synced.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "completionProvider",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides completion support."
+				},
+				{
+					"name": "hoverProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "HoverOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides hover support."
+				},
+				{
+					"name": "signatureHelpProvider",
+					"type": {
+						"kind": "reference",
+						"name": "SignatureHelpOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides signature help support."
+				},
+				{
+					"name": "declarationProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DeclarationOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "DeclarationRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides Goto Declaration support."
+				},
+				{
+					"name": "definitionProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DefinitionOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides goto definition support."
+				},
+				{
+					"name": "typeDefinitionProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "TypeDefinitionOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "TypeDefinitionRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides Goto Type Definition support."
+				},
+				{
+					"name": "implementationProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "ImplementationOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "ImplementationRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides Goto Implementation support."
+				},
+				{
+					"name": "referencesProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "ReferenceOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides find references support."
+				},
+				{
+					"name": "documentHighlightProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentHighlightOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides document highlight support."
+				},
+				{
+					"name": "documentSymbolProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentSymbolOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides document symbol support."
+				},
+				{
+					"name": "codeActionProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "CodeActionOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides code actions. CodeActionOptions may only be\nspecified if the client states that it supports\n`codeActionLiteralSupport` in its initial `initialize` request."
+				},
+				{
+					"name": "codeLensProvider",
+					"type": {
+						"kind": "reference",
+						"name": "CodeLensOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides code lens."
+				},
+				{
+					"name": "documentLinkProvider",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentLinkOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides document link support."
+				},
+				{
+					"name": "colorProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentColorOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentColorRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides color provider support."
+				},
+				{
+					"name": "workspaceSymbolProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "WorkspaceSymbolOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides workspace symbol support."
+				},
+				{
+					"name": "documentFormattingProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentFormattingOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides document formatting."
+				},
+				{
+					"name": "documentRangeFormattingProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "DocumentRangeFormattingOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides document range formatting."
+				},
+				{
+					"name": "documentOnTypeFormattingProvider",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentOnTypeFormattingOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides document formatting on typing."
+				},
+				{
+					"name": "renameProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "RenameOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides rename support. RenameOptions may only be\nspecified if the client states that it supports\n`prepareSupport` in its initial `initialize` request."
+				},
+				{
+					"name": "foldingRangeProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "FoldingRangeOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "FoldingRangeRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides folding provider support."
+				},
+				{
+					"name": "selectionRangeProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "SelectionRangeOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "SelectionRangeRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides selection range support."
+				},
+				{
+					"name": "executeCommandProvider",
+					"type": {
+						"kind": "reference",
+						"name": "ExecuteCommandOptions"
+					},
+					"optional": true,
+					"documentation": "The server provides execute command support."
+				},
+				{
+					"name": "callHierarchyProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "CallHierarchyOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "CallHierarchyRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides call hierarchy support.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "linkedEditingRangeProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "LinkedEditingRangeOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "LinkedEditingRangeRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides linked editing range support.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "semanticTokensProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "SemanticTokensOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "SemanticTokensRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides semantic tokens support.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "monikerProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "MonikerOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "MonikerRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides moniker support.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "typeHierarchyProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "TypeHierarchyOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "TypeHierarchyRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides type hierarchy support.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "inlineValueProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "InlineValueOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "InlineValueRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides inline values.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "inlayHintProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "InlayHintOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "InlayHintRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server provides inlay hints.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "diagnosticProvider",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "DiagnosticOptions"
+							},
+							{
+								"kind": "reference",
+								"name": "DiagnosticRegistrationOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The server has support for pull model diagnostics.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "workspace",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "workspaceFolders",
+									"type": {
+										"kind": "reference",
+										"name": "WorkspaceFoldersServerCapabilities"
+									},
+									"optional": true,
+									"documentation": "The server supports workspace folder.\n\n@since 3.6.0",
+									"since": "3.6.0"
+								},
+								{
+									"name": "fileOperations",
+									"type": {
+										"kind": "reference",
+										"name": "FileOperationOptions"
+									},
+									"optional": true,
+									"documentation": "The server is interested in notifications/requests for operations on files.\n\n@since 3.16.0",
+									"since": "3.16.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Workspace specific server capabilities."
+				},
+				{
+					"name": "experimental",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "Experimental server capabilities."
+				}
+			],
+			"documentation": "Defines the capabilities provided by a language\nserver."
+		},
+		{
+			"name": "VersionedTextDocumentIdentifier",
+			"properties": [
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "integer"
+					},
+					"documentation": "The version number of this document."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentIdentifier"
+				}
+			],
+			"documentation": "A text document identifier to denote a specific version of a text document."
+		},
+		{
+			"name": "SaveOptions",
+			"properties": [
+				{
+					"name": "includeText",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client is supposed to include the content on save."
+				}
+			],
+			"documentation": "Save options."
+		},
+		{
+			"name": "FileEvent",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The file's uri."
+				},
+				{
+					"name": "type",
+					"type": {
+						"kind": "reference",
+						"name": "FileChangeType"
+					},
+					"documentation": "The change type."
+				}
+			],
+			"documentation": "An event describing a file change."
+		},
+		{
+			"name": "FileSystemWatcher",
+			"properties": [
+				{
+					"name": "globPattern",
+					"type": {
+						"kind": "reference",
+						"name": "GlobPattern"
+					},
+					"documentation": "The glob pattern to watch. See {@link GlobPattern glob pattern} for more detail.\n\n@since 3.17.0 support for relative patterns.",
+					"since": "3.17.0 support for relative patterns."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "WatchKind"
+					},
+					"optional": true,
+					"documentation": "The kind of events of interest. If omitted it defaults\nto WatchKind.Create | WatchKind.Change | WatchKind.Delete\nwhich is 7."
+				}
+			]
+		},
+		{
+			"name": "Diagnostic",
+			"properties": [
+				{
+					"name": "range",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range at which the message applies"
+				},
+				{
+					"name": "severity",
+					"type": {
+						"kind": "reference",
+						"name": "DiagnosticSeverity"
+					},
+					"optional": true,
+					"documentation": "The diagnostic's severity. Can be omitted. If omitted it is up to the\nclient to interpret diagnostics as error, warning, info or hint."
+				},
+				{
+					"name": "code",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "string"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The diagnostic's code, which usually appear in the user interface."
+				},
+				{
+					"name": "codeDescription",
+					"type": {
+						"kind": "reference",
+						"name": "CodeDescription"
+					},
+					"optional": true,
+					"documentation": "An optional property to describe the error code.\nRequires the code field (above) to be present/not null.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "source",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A human-readable string describing the source of this\ndiagnostic, e.g. 'typescript' or 'super lint'. It usually\nappears in the user interface."
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The diagnostic's message. It usually appears in the user interface"
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DiagnosticTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Additional metadata about the diagnostic.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "relatedInformation",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "DiagnosticRelatedInformation"
+						}
+					},
+					"optional": true,
+					"documentation": "An array of related diagnostic information, e.g. when symbol-names within\na scope collide all definitions can be marked via this property."
+				},
+				{
+					"name": "data",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "A data entry field that is preserved between a `textDocument/publishDiagnostics`\nnotification and `textDocument/codeAction` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "Represents a diagnostic, such as a compiler error or warning. Diagnostic objects\nare only valid in the scope of a resource."
+		},
+		{
+			"name": "CompletionContext",
+			"properties": [
+				{
+					"name": "triggerKind",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionTriggerKind"
+					},
+					"documentation": "How the completion was triggered."
+				},
+				{
+					"name": "triggerCharacter",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The trigger character (a single character) that has trigger code complete.\nIs undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`"
+				}
+			],
+			"documentation": "Contains additional information about the context in which a completion request is triggered."
+		},
+		{
+			"name": "CompletionItemLabelDetails",
+			"properties": [
+				{
+					"name": "detail",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional string which is rendered less prominently directly after {@link CompletionItem.label label},\nwithout any spacing. Should be used for function signatures and type annotations."
+				},
+				{
+					"name": "description",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "An optional string which is rendered less prominently after {@link CompletionItem.detail}. Should be used\nfor fully qualified names and file paths."
+				}
+			],
+			"documentation": "Additional details for a completion item label.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InsertReplaceEdit",
+			"properties": [
+				{
+					"name": "newText",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The string to be inserted."
+				},
+				{
+					"name": "insert",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range if the insert is requested"
+				},
+				{
+					"name": "replace",
+					"type": {
+						"kind": "reference",
+						"name": "Range"
+					},
+					"documentation": "The range if the replace is requested."
+				}
+			],
+			"documentation": "A special text edit to provide an insert and a replace operation.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CompletionOptions",
+			"properties": [
+				{
+					"name": "triggerCharacters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "Most tools trigger completion request automatically without explicitly requesting\nit using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user\nstarts to type an identifier. For example if the user types `c` in a JavaScript file\ncode complete will automatically pop up present `console` besides others as a\ncompletion item. Characters that make up identifiers don't need to be listed here.\n\nIf code complete should automatically be trigger on characters not being valid inside\nan identifier (for example `.` in JavaScript) list them in `triggerCharacters`."
+				},
+				{
+					"name": "allCommitCharacters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "The list of all possible characters that commit a completion. This field can be used\nif clients don't support individual commit characters per completion item. See\n`ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`\n\nIf a server provides both `allCommitCharacters` and commit characters on an individual\ncompletion item the ones on the completion item win.\n\n@since 3.2.0",
+					"since": "3.2.0"
+				},
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The server provides support to resolve additional\ninformation for a completion item."
+				},
+				{
+					"name": "completionItem",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "labelDetailsSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "The server has support for completion item label\ndetails (see also `CompletionItemLabelDetails`) when\nreceiving a completion item in a resolve call.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The server supports the following `CompletionItem` specific\ncapabilities.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Completion options."
+		},
+		{
+			"name": "HoverOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Hover options."
+		},
+		{
+			"name": "SignatureHelpContext",
+			"properties": [
+				{
+					"name": "triggerKind",
+					"type": {
+						"kind": "reference",
+						"name": "SignatureHelpTriggerKind"
+					},
+					"documentation": "Action that caused signature help to be triggered."
+				},
+				{
+					"name": "triggerCharacter",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "Character that caused signature help to be triggered.\n\nThis is undefined when `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter`"
+				},
+				{
+					"name": "isRetrigger",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "`true` if signature help was already showing when it was triggered.\n\nRetriggers occurs when the signature help is already active and can be caused by actions such as\ntyping a trigger character, a cursor move, or document content changes."
+				},
+				{
+					"name": "activeSignatureHelp",
+					"type": {
+						"kind": "reference",
+						"name": "SignatureHelp"
+					},
+					"optional": true,
+					"documentation": "The currently active `SignatureHelp`.\n\nThe `activeSignatureHelp` has its `SignatureHelp.activeSignature` field updated based on\nthe user navigating through available signatures."
+				}
+			],
+			"documentation": "Additional information about the context in which a signature help request was triggered.\n\n@since 3.15.0",
+			"since": "3.15.0"
+		},
+		{
+			"name": "SignatureInformation",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The label of this signature. Will be shown in\nthe UI."
+				},
+				{
+					"name": "documentation",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The human-readable doc-comment of this signature. Will be shown\nin the UI but can be omitted."
+				},
+				{
+					"name": "parameters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "ParameterInformation"
+						}
+					},
+					"optional": true,
+					"documentation": "The parameters of this signature."
+				},
+				{
+					"name": "activeParameter",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The index of the active parameter.\n\nIf provided, this is used in place of `SignatureHelp.activeParameter`.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "Represents the signature of something callable. A signature\ncan have a label, like a function-name, a doc-comment, and\na set of parameters."
+		},
+		{
+			"name": "SignatureHelpOptions",
+			"properties": [
+				{
+					"name": "triggerCharacters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "List of characters that trigger signature help automatically."
+				},
+				{
+					"name": "retriggerCharacters",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "List of characters that re-trigger signature help.\n\nThese trigger characters are only active when signature help is already showing. All trigger characters\nare also counted as re-trigger characters.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Server Capabilities for a [SignatureHelpRequest](#SignatureHelpRequest)."
+		},
+		{
+			"name": "DefinitionOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Server Capabilities for a [DefinitionRequest](#DefinitionRequest)."
+		},
+		{
+			"name": "ReferenceContext",
+			"properties": [
+				{
+					"name": "includeDeclaration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "Include the declaration of the current symbol."
+				}
+			],
+			"documentation": "Value-object that contains additional information when\nrequesting references."
+		},
+		{
+			"name": "ReferenceOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Reference options."
+		},
+		{
+			"name": "DocumentHighlightOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [DocumentHighlightRequest](#DocumentHighlightRequest)."
+		},
+		{
+			"name": "BaseSymbolInformation",
+			"properties": [
+				{
+					"name": "name",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of this symbol."
+				},
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "SymbolKind"
+					},
+					"documentation": "The kind of this symbol."
+				},
+				{
+					"name": "tags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "SymbolTag"
+						}
+					},
+					"optional": true,
+					"documentation": "Tags for this symbol.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "containerName",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The name of the symbol containing this symbol. This information is for\nuser interface purposes (e.g. to render a qualifier in the user interface\nif necessary). It can't be used to re-infer a hierarchy for the document\nsymbols."
+				}
+			],
+			"documentation": "A base for all symbol information."
+		},
+		{
+			"name": "DocumentSymbolOptions",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A human-readable string that is shown when multiple outlines trees\nare shown for the same document.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [DocumentSymbolRequest](#DocumentSymbolRequest)."
+		},
+		{
+			"name": "CodeActionContext",
+			"properties": [
+				{
+					"name": "diagnostics",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Diagnostic"
+						}
+					},
+					"documentation": "An array of diagnostics known on the client side overlapping the range provided to the\n`textDocument/codeAction` request. They are provided so that the server knows which\nerrors are currently presented to the user for the given range. There is no guarantee\nthat these accurately reflect the error state of the resource. The primary parameter\nto compute code actions is the provided range."
+				},
+				{
+					"name": "only",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CodeActionKind"
+						}
+					},
+					"optional": true,
+					"documentation": "Requested kind of actions to return.\n\nActions not of this kind are filtered out by the client before being shown. So servers\ncan omit computing them."
+				},
+				{
+					"name": "triggerKind",
+					"type": {
+						"kind": "reference",
+						"name": "CodeActionTriggerKind"
+					},
+					"optional": true,
+					"documentation": "The reason why code actions were requested.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Contains additional diagnostic information about the context in which\na [code action](#CodeActionProvider.provideCodeActions) is run."
+		},
+		{
+			"name": "CodeActionOptions",
+			"properties": [
+				{
+					"name": "codeActionKinds",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "CodeActionKind"
+						}
+					},
+					"optional": true,
+					"documentation": "CodeActionKinds that this server may return.\n\nThe list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server\nmay list out every specific kind they provide."
+				},
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The server provides support to resolve additional\ninformation for a code action.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [CodeActionRequest](#CodeActionRequest)."
+		},
+		{
+			"name": "WorkspaceSymbolOptions",
+			"properties": [
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The server provides support to resolve additional\ninformation for a workspace symbol.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Server capabilities for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest)."
+		},
+		{
+			"name": "CodeLensOptions",
+			"properties": [
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Code lens has a resolve provider as well."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Code Lens provider options of a [CodeLensRequest](#CodeLensRequest)."
+		},
+		{
+			"name": "DocumentLinkOptions",
+			"properties": [
+				{
+					"name": "resolveProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Document links have a resolve provider as well."
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [DocumentLinkRequest](#DocumentLinkRequest)."
+		},
+		{
+			"name": "FormattingOptions",
+			"properties": [
+				{
+					"name": "tabSize",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "Size of a tab in spaces."
+				},
+				{
+					"name": "insertSpaces",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "Prefer spaces over tabs."
+				},
+				{
+					"name": "trimTrailingWhitespace",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Trim trailing whitespace on a line.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "insertFinalNewline",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Insert a newline character at the end of the file if one does not exist.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "trimFinalNewlines",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Trim all newlines after the final newline at the end of the file.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"documentation": "Value-object describing what options formatting should use."
+		},
+		{
+			"name": "DocumentFormattingOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [DocumentFormattingRequest](#DocumentFormattingRequest)."
+		},
+		{
+			"name": "DocumentRangeFormattingOptions",
+			"properties": [],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest)."
+		},
+		{
+			"name": "DocumentOnTypeFormattingOptions",
+			"properties": [
+				{
+					"name": "firstTriggerCharacter",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "A character on which formatting should be triggered, like `{`."
+				},
+				{
+					"name": "moreTriggerCharacter",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "More trigger characters."
+				}
+			],
+			"documentation": "Provider options for a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest)."
+		},
+		{
+			"name": "RenameOptions",
+			"properties": [
+				{
+					"name": "prepareProvider",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Renames should be checked and tested before being executed.\n\n@since version 3.12.0",
+					"since": "version 3.12.0"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "Provider options for a [RenameRequest](#RenameRequest)."
+		},
+		{
+			"name": "ExecuteCommandOptions",
+			"properties": [
+				{
+					"name": "commands",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"documentation": "The commands to be executed on the server"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "WorkDoneProgressOptions"
+				}
+			],
+			"documentation": "The server capabilities of a [ExecuteCommandRequest](#ExecuteCommandRequest)."
+		},
+		{
+			"name": "SemanticTokensLegend",
+			"properties": [
+				{
+					"name": "tokenTypes",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"documentation": "The token types a server uses."
+				},
+				{
+					"name": "tokenModifiers",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"documentation": "The token modifiers a server uses."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "OptionalVersionedTextDocumentIdentifier",
+			"properties": [
+				{
+					"name": "version",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "The version number of this document. If a versioned text document identifier\nis sent from the server to the client and the file is not open in the editor\n(the server has not received an open notification before) the server can send\n`null` to indicate that the version is unknown and the content on disk is the\ntruth (as specified with document content ownership)."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextDocumentIdentifier"
+				}
+			],
+			"documentation": "A text document identifier to optionally denote a specific version of a text document."
+		},
+		{
+			"name": "AnnotatedTextEdit",
+			"properties": [
+				{
+					"name": "annotationId",
+					"type": {
+						"kind": "reference",
+						"name": "ChangeAnnotationIdentifier"
+					},
+					"documentation": "The actual identifier of the change annotation"
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "TextEdit"
+				}
+			],
+			"documentation": "A special text edit with an additional change annotation.\n\n@since 3.16.0.",
+			"since": "3.16.0."
+		},
+		{
+			"name": "ResourceOperation",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The resource operation kind."
+				},
+				{
+					"name": "annotationId",
+					"type": {
+						"kind": "reference",
+						"name": "ChangeAnnotationIdentifier"
+					},
+					"optional": true,
+					"documentation": "An optional annotation identifier describing the operation.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "A generic resource operation."
+		},
+		{
+			"name": "CreateFileOptions",
+			"properties": [
+				{
+					"name": "overwrite",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Overwrite existing file. Overwrite wins over `ignoreIfExists`"
+				},
+				{
+					"name": "ignoreIfExists",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Ignore if exists."
+				}
+			],
+			"documentation": "Options to create a file."
+		},
+		{
+			"name": "RenameFileOptions",
+			"properties": [
+				{
+					"name": "overwrite",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Overwrite target if existing. Overwrite wins over `ignoreIfExists`"
+				},
+				{
+					"name": "ignoreIfExists",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Ignores if target exists."
+				}
+			],
+			"documentation": "Rename file options"
+		},
+		{
+			"name": "DeleteFileOptions",
+			"properties": [
+				{
+					"name": "recursive",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Delete the content recursively if a folder is denoted."
+				},
+				{
+					"name": "ignoreIfNotExists",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Ignore the operation if the file doesn't exist."
+				}
+			],
+			"documentation": "Delete file options"
+		},
+		{
+			"name": "FileOperationPattern",
+			"properties": [
+				{
+					"name": "glob",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The glob pattern to match. Glob patterns can have the following syntax:\n- `*` to match one or more characters in a path segment\n- `?` to match on one character in a path segment\n- `**` to match any number of path segments, including none\n- `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)\n- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n- `[!...]` 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`)"
+				},
+				{
+					"name": "matches",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationPatternKind"
+					},
+					"optional": true,
+					"documentation": "Whether to match files or folders with this pattern.\n\nMatches both if undefined."
+				},
+				{
+					"name": "options",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationPatternOptions"
+					},
+					"optional": true,
+					"documentation": "Additional options used during matching."
+				}
+			],
+			"documentation": "A pattern to describe in which file operation requests or notifications\nthe server is interested in receiving.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "WorkspaceFullDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The URI for which diagnostic information is reported."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "The version number for which the diagnostics are reported.\nIf the document is not marked as open `null` can be provided."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "FullDocumentDiagnosticReport"
+				}
+			],
+			"documentation": "A full document diagnostic report for a workspace diagnostic result.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceUnchangedDocumentDiagnosticReport",
+			"properties": [
+				{
+					"name": "uri",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The URI for which diagnostic information is reported."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "integer"
+							},
+							{
+								"kind": "base",
+								"name": "null"
+							}
+						]
+					},
+					"documentation": "The version number for which the diagnostics are reported.\nIf the document is not marked as open `null` can be provided."
+				}
+			],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "UnchangedDocumentDiagnosticReport"
+				}
+			],
+			"documentation": "An unchanged document diagnostic report for a workspace diagnostic result.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "LSPObject",
+			"properties": [],
+			"documentation": "LSP object definition.\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookCell",
+			"properties": [
+				{
+					"name": "kind",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookCellKind"
+					},
+					"documentation": "The cell's kind"
+				},
+				{
+					"name": "document",
+					"type": {
+						"kind": "base",
+						"name": "DocumentUri"
+					},
+					"documentation": "The URI of the cell's text document\ncontent."
+				},
+				{
+					"name": "metadata",
+					"type": {
+						"kind": "reference",
+						"name": "LSPObject"
+					},
+					"optional": true,
+					"documentation": "Additional metadata stored with the cell.\n\nNote: should always be an object literal (e.g. LSPObject)"
+				},
+				{
+					"name": "executionSummary",
+					"type": {
+						"kind": "reference",
+						"name": "ExecutionSummary"
+					},
+					"optional": true,
+					"documentation": "Additional execution summary information\nif supported by the client."
+				}
+			],
+			"documentation": "A notebook cell.\n\nA cell's document URI must be unique across ALL notebook\ncells and can therefore be used to uniquely identify a\nnotebook cell or the cell's text document.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookCellArrayChange",
+			"properties": [
+				{
+					"name": "start",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The start oftest of the cell that changed."
+				},
+				{
+					"name": "deleteCount",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "The deleted cells"
+				},
+				{
+					"name": "cells",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "NotebookCell"
+						}
+					},
+					"optional": true,
+					"documentation": "The new cells, if any"
+				}
+			],
+			"documentation": "A change describing how to move a `NotebookCell`\narray from state S to S'.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "ClientCapabilities",
+			"properties": [
+				{
+					"name": "workspace",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Workspace specific client capabilities."
+				},
+				{
+					"name": "textDocument",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Text document specific client capabilities."
+				},
+				{
+					"name": "notebookDocument",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocumentClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the notebook document support.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "window",
+					"type": {
+						"kind": "reference",
+						"name": "WindowClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Window specific client capabilities."
+				},
+				{
+					"name": "general",
+					"type": {
+						"kind": "reference",
+						"name": "GeneralClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "General client capabilities.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "experimental",
+					"type": {
+						"kind": "reference",
+						"name": "LSPAny"
+					},
+					"optional": true,
+					"documentation": "Experimental client capabilities."
+				}
+			],
+			"documentation": "Defines the capabilities provided by the client."
+		},
+		{
+			"name": "TextDocumentSyncOptions",
+			"properties": [
+				{
+					"name": "openClose",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Open and close notifications are sent to the server. If omitted open close notification should not\nbe sent."
+				},
+				{
+					"name": "change",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentSyncKind"
+					},
+					"optional": true,
+					"documentation": "Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full\nand TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None."
+				},
+				{
+					"name": "willSave",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "If present will save notifications are sent to the server. If omitted the notification should not be\nsent."
+				},
+				{
+					"name": "willSaveWaitUntil",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "If present will save wait until requests are sent to the server. If omitted the request should not be\nsent."
+				},
+				{
+					"name": "save",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "boolean"
+							},
+							{
+								"kind": "reference",
+								"name": "SaveOptions"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "If present save notifications are sent to the server. If omitted the notification should not be\nsent."
+				}
+			]
+		},
+		{
+			"name": "NotebookDocumentSyncOptions",
+			"properties": [
+				{
+					"name": "notebookSelector",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "or",
+							"items": [
+								{
+									"kind": "literal",
+									"value": {
+										"properties": [
+											{
+												"name": "notebook",
+												"type": {
+													"kind": "or",
+													"items": [
+														{
+															"kind": "base",
+															"name": "string"
+														},
+														{
+															"kind": "reference",
+															"name": "NotebookDocumentFilter"
+														}
+													]
+												},
+												"documentation": "The notebook to be synced If a string\nvalue is provided it matches against the\nnotebook type. '*' matches every notebook."
+											},
+											{
+												"name": "cells",
+												"type": {
+													"kind": "array",
+													"element": {
+														"kind": "literal",
+														"value": {
+															"properties": [
+																{
+																	"name": "language",
+																	"type": {
+																		"kind": "base",
+																		"name": "string"
+																	}
+																}
+															]
+														}
+													}
+												},
+												"optional": true,
+												"documentation": "The cells of the matching notebook to be synced."
+											}
+										]
+									}
+								},
+								{
+									"kind": "literal",
+									"value": {
+										"properties": [
+											{
+												"name": "notebook",
+												"type": {
+													"kind": "or",
+													"items": [
+														{
+															"kind": "base",
+															"name": "string"
+														},
+														{
+															"kind": "reference",
+															"name": "NotebookDocumentFilter"
+														}
+													]
+												},
+												"optional": true,
+												"documentation": "The notebook to be synced If a string\nvalue is provided it matches against the\nnotebook type. '*' matches every notebook."
+											},
+											{
+												"name": "cells",
+												"type": {
+													"kind": "array",
+													"element": {
+														"kind": "literal",
+														"value": {
+															"properties": [
+																{
+																	"name": "language",
+																	"type": {
+																		"kind": "base",
+																		"name": "string"
+																	}
+																}
+															]
+														}
+													}
+												},
+												"documentation": "The cells of the matching notebook to be synced."
+											}
+										]
+									}
+								}
+							]
+						}
+					},
+					"documentation": "The notebooks to be synced"
+				},
+				{
+					"name": "save",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether save notification should be forwarded to\nthe server. Will only be honored if mode === `notebook`."
+				}
+			],
+			"documentation": "Options specific to a notebook plus its cells\nto be synced to the server.\n\nIf a selector provides a notebook document\nfilter but no cell selector all cells of a\nmatching notebook document will be synced.\n\nIf a selector provides no notebook document\nfilter but only a cell selector all notebook\ndocument that contain at least one matching\ncell will be synced.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocumentSyncRegistrationOptions",
+			"properties": [],
+			"extends": [
+				{
+					"kind": "reference",
+					"name": "NotebookDocumentSyncOptions"
+				}
+			],
+			"mixins": [
+				{
+					"kind": "reference",
+					"name": "StaticRegistrationOptions"
+				}
+			],
+			"documentation": "Registration options specific to a notebook.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceFoldersServerCapabilities",
+			"properties": [
+				{
+					"name": "supported",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The server has support for workspace folders"
+				},
+				{
+					"name": "changeNotifications",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "base",
+								"name": "boolean"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "Whether the server wants to receive workspace folder\nchange notifications.\n\nIf a string is provided the string is treated as an ID\nunder which the notification is registered on the client\nside. The ID can be used to unregister for these events\nusing the `client/unregisterCapability` request."
+				}
+			]
+		},
+		{
+			"name": "FileOperationOptions",
+			"properties": [
+				{
+					"name": "didCreate",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving didCreateFiles notifications."
+				},
+				{
+					"name": "willCreate",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving willCreateFiles requests."
+				},
+				{
+					"name": "didRename",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving didRenameFiles notifications."
+				},
+				{
+					"name": "willRename",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving willRenameFiles requests."
+				},
+				{
+					"name": "didDelete",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving didDeleteFiles file notifications."
+				},
+				{
+					"name": "willDelete",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationRegistrationOptions"
+					},
+					"optional": true,
+					"documentation": "The server is interested in receiving willDeleteFiles file requests."
+				}
+			],
+			"documentation": "Options for notifications/requests for user operations on files.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "T",
+			"properties": []
+		},
+		{
+			"name": "CodeDescription",
+			"properties": [
+				{
+					"name": "href",
+					"type": {
+						"kind": "reference",
+						"name": "URI"
+					},
+					"documentation": "An URI to open with more information about the diagnostic error."
+				}
+			],
+			"documentation": "Structure to capture a description for an error code.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "DiagnosticRelatedInformation",
+			"properties": [
+				{
+					"name": "location",
+					"type": {
+						"kind": "reference",
+						"name": "Location"
+					},
+					"documentation": "The location of this related diagnostic information."
+				},
+				{
+					"name": "message",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The message of this related diagnostic information."
+				}
+			],
+			"documentation": "Represents a related message and source code location for a diagnostic. This should be\nused to point to code locations that cause or related to a diagnostics, e.g when duplicating\na symbol in a scope."
+		},
+		{
+			"name": "ParameterInformation",
+			"properties": [
+				{
+					"name": "label",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "tuple",
+								"items": [
+									{
+										"kind": "base",
+										"name": "uinteger"
+									},
+									{
+										"kind": "base",
+										"name": "uinteger"
+									}
+								]
+							}
+						]
+					},
+					"documentation": "The label of this parameter information.\n\nEither a string or an inclusive start and exclusive end offsets within its containing\nsignature label. (see SignatureInformation.label). The offsets are based on a UTF-16\nstring representation as `Position` and `Range` does.\n\n*Note*: a label of type string should be a substring of its containing signature label.\nIts intended use case is to highlight the parameter label part in the `SignatureInformation.label`."
+				},
+				{
+					"name": "documentation",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "MarkupContent"
+							}
+						]
+					},
+					"optional": true,
+					"documentation": "The human-readable doc-comment of this parameter. Will be shown\nin the UI but can be omitted."
+				}
+			],
+			"documentation": "Represents a parameter of a callable-signature. A parameter can\nhave a label and a doc-comment."
+		},
+		{
+			"name": "NotebookCellTextDocumentFilter",
+			"properties": [
+				{
+					"name": "notebook",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "base",
+								"name": "string"
+							},
+							{
+								"kind": "reference",
+								"name": "NotebookDocumentFilter"
+							}
+						]
+					},
+					"documentation": "A filter that matches against the notebook\ncontaining the notebook cell. If a string\nvalue is provided it matches against the\nnotebook type. '*' matches every notebook."
+				},
+				{
+					"name": "language",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "A language id like `python`.\n\nWill be matched against the language id of the\nnotebook cell document. '*' matches every language."
+				}
+			],
+			"documentation": "A notebook cell text document filter denotes a cell text\ndocument by different properties.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "FileOperationPatternOptions",
+			"properties": [
+				{
+					"name": "ignoreCase",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The pattern should be matched ignoring casing."
+				}
+			],
+			"documentation": "Matching options for the file operation pattern.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "ExecutionSummary",
+			"properties": [
+				{
+					"name": "executionOrder",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"documentation": "A strict monotonically increasing value\nindicating the execution order of a cell\ninside a notebook."
+				},
+				{
+					"name": "success",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the execution was successful or\nnot if known by the client."
+				}
+			]
+		},
+		{
+			"name": "WorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "applyEdit",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports applying batch edits\nto the workspace by supporting the request\n'workspace/applyEdit'"
+				},
+				{
+					"name": "workspaceEdit",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceEditClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to `WorkspaceEdit`s."
+				},
+				{
+					"name": "didChangeConfiguration",
+					"type": {
+						"kind": "reference",
+						"name": "DidChangeConfigurationClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `workspace/didChangeConfiguration` notification."
+				},
+				{
+					"name": "didChangeWatchedFiles",
+					"type": {
+						"kind": "reference",
+						"name": "DidChangeWatchedFilesClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `workspace/didChangeWatchedFiles` notification."
+				},
+				{
+					"name": "symbol",
+					"type": {
+						"kind": "reference",
+						"name": "WorkspaceSymbolClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `workspace/symbol` request."
+				},
+				{
+					"name": "executeCommand",
+					"type": {
+						"kind": "reference",
+						"name": "ExecuteCommandClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `workspace/executeCommand` request."
+				},
+				{
+					"name": "workspaceFolders",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for workspace folders.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				},
+				{
+					"name": "configuration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports `workspace/configuration` requests.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				},
+				{
+					"name": "semanticTokens",
+					"type": {
+						"kind": "reference",
+						"name": "SemanticTokensWorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the semantic token requests scoped to the\nworkspace.\n\n@since 3.16.0.",
+					"since": "3.16.0."
+				},
+				{
+					"name": "codeLens",
+					"type": {
+						"kind": "reference",
+						"name": "CodeLensWorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the code lens requests scoped to the\nworkspace.\n\n@since 3.16.0.",
+					"since": "3.16.0."
+				},
+				{
+					"name": "fileOperations",
+					"type": {
+						"kind": "reference",
+						"name": "FileOperationClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "The client has support for file notifications/requests for user operations on files.\n\nSince 3.16.0"
+				},
+				{
+					"name": "inlineValue",
+					"type": {
+						"kind": "reference",
+						"name": "InlineValueWorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the inline values requests scoped to the\nworkspace.\n\n@since 3.17.0.",
+					"since": "3.17.0."
+				},
+				{
+					"name": "inlayHint",
+					"type": {
+						"kind": "reference",
+						"name": "InlayHintWorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the inlay hint requests scoped to the\nworkspace.\n\n@since 3.17.0.",
+					"since": "3.17.0."
+				},
+				{
+					"name": "diagnostics",
+					"type": {
+						"kind": "reference",
+						"name": "DiagnosticWorkspaceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the diagnostic requests scoped to the\nworkspace.\n\n@since 3.17.0.",
+					"since": "3.17.0."
+				}
+			],
+			"documentation": "Workspace specific client capabilities."
+		},
+		{
+			"name": "TextDocumentClientCapabilities",
+			"properties": [
+				{
+					"name": "synchronization",
+					"type": {
+						"kind": "reference",
+						"name": "TextDocumentSyncClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Defines which synchronization capabilities the client supports."
+				},
+				{
+					"name": "completion",
+					"type": {
+						"kind": "reference",
+						"name": "CompletionClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/completion` request."
+				},
+				{
+					"name": "hover",
+					"type": {
+						"kind": "reference",
+						"name": "HoverClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/hover` request."
+				},
+				{
+					"name": "signatureHelp",
+					"type": {
+						"kind": "reference",
+						"name": "SignatureHelpClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/signatureHelp` request."
+				},
+				{
+					"name": "declaration",
+					"type": {
+						"kind": "reference",
+						"name": "DeclarationClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/declaration` request.\n\n@since 3.14.0",
+					"since": "3.14.0"
+				},
+				{
+					"name": "definition",
+					"type": {
+						"kind": "reference",
+						"name": "DefinitionClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/definition` request."
+				},
+				{
+					"name": "typeDefinition",
+					"type": {
+						"kind": "reference",
+						"name": "TypeDefinitionClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/typeDefinition` request.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				},
+				{
+					"name": "implementation",
+					"type": {
+						"kind": "reference",
+						"name": "ImplementationClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/implementation` request.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				},
+				{
+					"name": "references",
+					"type": {
+						"kind": "reference",
+						"name": "ReferenceClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/references` request."
+				},
+				{
+					"name": "documentHighlight",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentHighlightClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/documentHighlight` request."
+				},
+				{
+					"name": "documentSymbol",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentSymbolClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/documentSymbol` request."
+				},
+				{
+					"name": "codeAction",
+					"type": {
+						"kind": "reference",
+						"name": "CodeActionClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/codeAction` request."
+				},
+				{
+					"name": "codeLens",
+					"type": {
+						"kind": "reference",
+						"name": "CodeLensClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/codeLens` request."
+				},
+				{
+					"name": "documentLink",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentLinkClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/documentLink` request."
+				},
+				{
+					"name": "colorProvider",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentColorClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/documentColor` and the\n`textDocument/colorPresentation` request.\n\n@since 3.6.0",
+					"since": "3.6.0"
+				},
+				{
+					"name": "formatting",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentFormattingClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/formatting` request."
+				},
+				{
+					"name": "rangeFormatting",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentRangeFormattingClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/rangeFormatting` request."
+				},
+				{
+					"name": "onTypeFormatting",
+					"type": {
+						"kind": "reference",
+						"name": "DocumentOnTypeFormattingClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/onTypeFormatting` request."
+				},
+				{
+					"name": "rename",
+					"type": {
+						"kind": "reference",
+						"name": "RenameClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/rename` request."
+				},
+				{
+					"name": "foldingRange",
+					"type": {
+						"kind": "reference",
+						"name": "FoldingRangeClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/foldingRange` request.\n\n@since 3.10.0",
+					"since": "3.10.0"
+				},
+				{
+					"name": "selectionRange",
+					"type": {
+						"kind": "reference",
+						"name": "SelectionRangeClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/selectionRange` request.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "publishDiagnostics",
+					"type": {
+						"kind": "reference",
+						"name": "PublishDiagnosticsClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/publishDiagnostics` notification."
+				},
+				{
+					"name": "callHierarchy",
+					"type": {
+						"kind": "reference",
+						"name": "CallHierarchyClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the various call hierarchy requests.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "semanticTokens",
+					"type": {
+						"kind": "reference",
+						"name": "SemanticTokensClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the various semantic token request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "linkedEditingRange",
+					"type": {
+						"kind": "reference",
+						"name": "LinkedEditingRangeClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/linkedEditingRange` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "moniker",
+					"type": {
+						"kind": "reference",
+						"name": "MonikerClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Client capabilities specific to the `textDocument/moniker` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "typeHierarchy",
+					"type": {
+						"kind": "reference",
+						"name": "TypeHierarchyClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the various type hierarchy requests.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "inlineValue",
+					"type": {
+						"kind": "reference",
+						"name": "InlineValueClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/inlineValue` request.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "inlayHint",
+					"type": {
+						"kind": "reference",
+						"name": "InlayHintClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `textDocument/inlayHint` request.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "diagnostic",
+					"type": {
+						"kind": "reference",
+						"name": "DiagnosticClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the diagnostic pull model.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Text document specific client capabilities."
+		},
+		{
+			"name": "NotebookDocumentClientCapabilities",
+			"properties": [
+				{
+					"name": "synchronization",
+					"type": {
+						"kind": "reference",
+						"name": "NotebookDocumentSyncClientCapabilities"
+					},
+					"documentation": "Capabilities specific to notebook document synchronization\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Capabilities specific to the notebook document support.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WindowClientCapabilities",
+			"properties": [
+				{
+					"name": "workDoneProgress",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "It indicates whether the client supports server initiated\nprogress using the `window/workDoneProgress/create` request.\n\nThe capability also controls Whether client supports handling\nof progress notifications. If set servers are allowed to report a\n`workDoneProgress` property in the request specific server\ncapabilities.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "showMessage",
+					"type": {
+						"kind": "reference",
+						"name": "ShowMessageRequestClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the showMessage request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "showDocument",
+					"type": {
+						"kind": "reference",
+						"name": "ShowDocumentClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the showDocument request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			]
+		},
+		{
+			"name": "GeneralClientCapabilities",
+			"properties": [
+				{
+					"name": "staleRequestSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "cancel",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"documentation": "The client will actively cancel the request."
+								},
+								{
+									"name": "retryOnContentModified",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"documentation": "The list of requests for which the client\nwill retry the request if it receives a\nresponse with error code `ContentModified`"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Client capability that signals how the client\nhandles stale requests (e.g. a request\nfor which the client will not process the response\nanymore since the information is outdated).\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "regularExpressions",
+					"type": {
+						"kind": "reference",
+						"name": "RegularExpressionsClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Client capabilities specific to regular expressions.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "markdown",
+					"type": {
+						"kind": "reference",
+						"name": "MarkdownClientCapabilities"
+					},
+					"optional": true,
+					"documentation": "Client capabilities specific to the client's markdown parser.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "positionEncodings",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "PositionEncodingKind"
+						}
+					},
+					"optional": true,
+					"documentation": "The position encodings supported by the client. Client and server\nhave to agree on the same position encoding to ensure that offsets\n(e.g. character position in a line) are interpreted the same on both\nsides.\n\nTo keep the protocol backwards compatible the following applies: if\nthe value 'utf-16' is missing from the array of position encodings\nservers can assume that the client supports UTF-16. UTF-16 is\ntherefore a mandatory encoding.\n\nIf omitted it defaults to ['utf-16'].\n\nImplementation considerations: since the conversion from one encoding\ninto another requires the content of the file / line the conversion\nis best done where the file is read which is usually on the server\nside.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "General client capabilities.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "RelativePattern",
+			"properties": [
+				{
+					"name": "baseUri",
+					"type": {
+						"kind": "or",
+						"items": [
+							{
+								"kind": "reference",
+								"name": "WorkspaceFolder"
+							},
+							{
+								"kind": "reference",
+								"name": "URI"
+							}
+						]
+					},
+					"documentation": "A workspace folder or a base URI to which this pattern will be matched\nagainst relatively."
+				},
+				{
+					"name": "pattern",
+					"type": {
+						"kind": "reference",
+						"name": "Pattern"
+					},
+					"documentation": "The actual glob pattern;"
+				}
+			],
+			"documentation": "A relative pattern is a helper to construct glob patterns that are matched\nrelatively to a base URI. The common value for a `baseUri` is a workspace\nfolder root, but it can be another absolute URI as well.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "WorkspaceEditClientCapabilities",
+			"properties": [
+				{
+					"name": "documentChanges",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports versioned document changes in `WorkspaceEdit`s"
+				},
+				{
+					"name": "resourceOperations",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "ResourceOperationKind"
+						}
+					},
+					"optional": true,
+					"documentation": "The resource operations the client supports. Clients should at least\nsupport 'create', 'rename' and 'delete' files and folders.\n\n@since 3.13.0",
+					"since": "3.13.0"
+				},
+				{
+					"name": "failureHandling",
+					"type": {
+						"kind": "reference",
+						"name": "FailureHandlingKind"
+					},
+					"optional": true,
+					"documentation": "The failure handling strategy of a client if applying the workspace edit\nfails.\n\n@since 3.13.0",
+					"since": "3.13.0"
+				},
+				{
+					"name": "normalizesLineEndings",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client normalizes line endings to the client specific\nsetting.\nIf set to `true` the client will normalize line ending characters\nin a workspace edit to the client-specified new line\ncharacter.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "changeAnnotationSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "groupsOnLabel",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Whether the client groups edits with equal labels into tree nodes,\nfor instance all edits labelled with \"Changes in Strings\" would\nbe a tree node."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Whether the client in general supports change annotations on text edits,\ncreate file, rename file and delete file changes.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			]
+		},
+		{
+			"name": "DidChangeConfigurationClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Did change configuration notification supports dynamic registration."
+				}
+			]
+		},
+		{
+			"name": "DidChangeWatchedFilesClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Did change watched files notification supports dynamic registration. Please note\nthat the current protocol doesn't support static configuration for file changes\nfrom the server side."
+				},
+				{
+					"name": "relativePatternSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client has support for {@link  RelativePattern relative pattern}\nor not.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			]
+		},
+		{
+			"name": "WorkspaceSymbolClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Symbol request supports dynamic registration."
+				},
+				{
+					"name": "symbolKind",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "SymbolKind"
+										}
+									},
+									"optional": true,
+									"documentation": "The symbol kind values the client supports. When this\nproperty exists the client also guarantees that it will\nhandle values outside its set gracefully and falls back\nto a default value when unknown.\n\nIf this property is not present the client only supports\nthe symbol kinds from `File` to `Array` as defined in\nthe initial version of the protocol."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Specific capabilities for the `SymbolKind` in the `workspace/symbol` request."
+				},
+				{
+					"name": "tagSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "SymbolTag"
+										}
+									},
+									"documentation": "The tags supported by the client."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client supports tags on `SymbolInformation`.\nClients supporting tags have to handle unknown tags gracefully.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "resolveSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "properties",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"documentation": "The properties that a client can resolve lazily. Usually\n`location.range`"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client support partial workspace symbols. The client will send the\nrequest `workspaceSymbol/resolve` to the server to resolve additional\nproperties.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Client capabilities for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest)."
+		},
+		{
+			"name": "ExecuteCommandClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Execute command supports dynamic registration."
+				}
+			],
+			"documentation": "The client capabilities of a [ExecuteCommandRequest](#ExecuteCommandRequest)."
+		},
+		{
+			"name": "SemanticTokensWorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "refreshSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client implementation supports a refresh request sent from\nthe server to the client.\n\nNote that this event is global and will force the client to refresh all\nsemantic tokens currently shown. It should be used with absolute care\nand is useful for situation where a server for example detects a project\nwide change that requires such a calculation."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "CodeLensWorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "refreshSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client implementation supports a refresh request sent from the\nserver to the client.\n\nNote that this event is global and will force the client to refresh all\ncode lenses currently shown. It should be used with absolute care and is\nuseful for situation where a server for example detect a project wide\nchange that requires such a calculation."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "FileOperationClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client supports dynamic registration for file requests/notifications."
+				},
+				{
+					"name": "didCreate",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending didCreateFiles notifications."
+				},
+				{
+					"name": "willCreate",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending willCreateFiles requests."
+				},
+				{
+					"name": "didRename",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending didRenameFiles notifications."
+				},
+				{
+					"name": "willRename",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending willRenameFiles requests."
+				},
+				{
+					"name": "didDelete",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending didDeleteFiles notifications."
+				},
+				{
+					"name": "willDelete",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client has support for sending willDeleteFiles requests."
+				}
+			],
+			"documentation": "Capabilities relating to events from file operations by the user in the client.\n\nThese events do not come from the file system, they come from user operations\nlike renaming a file in the UI.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "InlineValueWorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "refreshSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client implementation supports a refresh request sent from the\nserver to the client.\n\nNote that this event is global and will force the client to refresh all\ninline values currently shown. It should be used with absolute care and is\nuseful for situation where a server for example detects a project wide\nchange that requires such a calculation."
+				}
+			],
+			"documentation": "Client workspace capabilities specific to inline values.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHintWorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "refreshSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client implementation supports a refresh request sent from\nthe server to the client.\n\nNote that this event is global and will force the client to refresh all\ninlay hints currently shown. It should be used with absolute care and\nis useful for situation where a server for example detects a project wide\nchange that requires such a calculation."
+				}
+			],
+			"documentation": "Client workspace capabilities specific to inlay hints.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DiagnosticWorkspaceClientCapabilities",
+			"properties": [
+				{
+					"name": "refreshSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client implementation supports a refresh request sent from\nthe server to the client.\n\nNote that this event is global and will force the client to refresh all\npulled diagnostics currently shown. It should be used with absolute care and\nis useful for situation where a server for example detects a project wide\nchange that requires such a calculation."
+				}
+			],
+			"documentation": "Workspace client capabilities specific to diagnostic pull requests.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TextDocumentSyncClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether text document synchronization supports dynamic registration."
+				},
+				{
+					"name": "willSave",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports sending will save notifications."
+				},
+				{
+					"name": "willSaveWaitUntil",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports sending a will save request and\nwaits for a response providing text edits which will\nbe applied to the document before it is saved."
+				},
+				{
+					"name": "didSave",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports did save notifications."
+				}
+			]
+		},
+		{
+			"name": "CompletionClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether completion supports dynamic registration."
+				},
+				{
+					"name": "completionItem",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "snippetSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Client supports snippets as insert text.\n\nA snippet can define tab stops and placeholders with `$1`, `$2`\nand `${3:foo}`. `$0` defines the final tab stop, it defaults to\nthe end of the snippet. Placeholders with equal identifiers are linked,\nthat is typing in one will update others too."
+								},
+								{
+									"name": "commitCharactersSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Client supports commit characters on a completion item."
+								},
+								{
+									"name": "documentationFormat",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "MarkupKind"
+										}
+									},
+									"optional": true,
+									"documentation": "Client supports the following content formats for the documentation\nproperty. The order describes the preferred format of the client."
+								},
+								{
+									"name": "deprecatedSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Client supports the deprecated property on a completion item."
+								},
+								{
+									"name": "preselectSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Client supports the preselect property on a completion item."
+								},
+								{
+									"name": "tagSupport",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "valueSet",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "reference",
+															"name": "CompletionItemTag"
+														}
+													},
+													"documentation": "The tags supported by the client."
+												}
+											]
+										}
+									},
+									"optional": true,
+									"documentation": "Client supports the tag property on a completion item. Clients supporting\ntags have to handle unknown tags gracefully. Clients especially need to\npreserve unknown tags when sending a completion item back to the server in\na resolve call.\n\n@since 3.15.0",
+									"since": "3.15.0"
+								},
+								{
+									"name": "insertReplaceSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Client support insert replace edit to control different behavior if a\ncompletion item is inserted in the text or should replace text.\n\n@since 3.16.0",
+									"since": "3.16.0"
+								},
+								{
+									"name": "resolveSupport",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "properties",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "base",
+															"name": "string"
+														}
+													},
+													"documentation": "The properties that a client can resolve lazily."
+												}
+											]
+										}
+									},
+									"optional": true,
+									"documentation": "Indicates which properties a client can resolve lazily on a completion\nitem. Before version 3.16.0 only the predefined properties `documentation`\nand `details` could be resolved lazily.\n\n@since 3.16.0",
+									"since": "3.16.0"
+								},
+								{
+									"name": "insertTextModeSupport",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "valueSet",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "reference",
+															"name": "InsertTextMode"
+														}
+													}
+												}
+											]
+										}
+									},
+									"optional": true,
+									"documentation": "The client supports the `insertTextMode` property on\na completion item to override the whitespace handling mode\nas defined by the client (see `insertTextMode`).\n\n@since 3.16.0",
+									"since": "3.16.0"
+								},
+								{
+									"name": "labelDetailsSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "The client has support for completion item label\ndetails (see also `CompletionItemLabelDetails`).\n\n@since 3.17.0",
+									"since": "3.17.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client supports the following `CompletionItem` specific\ncapabilities."
+				},
+				{
+					"name": "completionItemKind",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "CompletionItemKind"
+										}
+									},
+									"optional": true,
+									"documentation": "The completion item kind values the client supports. When this\nproperty exists the client also guarantees that it will\nhandle values outside its set gracefully and falls back\nto a default value when unknown.\n\nIf this property is not present the client only supports\nthe completion items kinds from `Text` to `Reference` as defined in\nthe initial version of the protocol."
+								}
+							]
+						}
+					},
+					"optional": true
+				},
+				{
+					"name": "insertTextMode",
+					"type": {
+						"kind": "reference",
+						"name": "InsertTextMode"
+					},
+					"optional": true,
+					"documentation": "Defines how the client handles whitespace and indentation\nwhen accepting a completion item that uses multi line\ntext in either `insertText` or `textEdit`.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "contextSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports to send additional context information for a\n`textDocument/completion` request."
+				},
+				{
+					"name": "completionList",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "itemDefaults",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"optional": true,
+									"documentation": "The client supports the following itemDefaults on\na completion list.\n\nThe value lists the supported property names of the\n`CompletionList.itemDefaults` object. If omitted\nno properties are supported.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client supports the following `CompletionList` specific\ncapabilities.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Completion client capabilities"
+		},
+		{
+			"name": "HoverClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether hover supports dynamic registration."
+				},
+				{
+					"name": "contentFormat",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "MarkupKind"
+						}
+					},
+					"optional": true,
+					"documentation": "Client supports the following content formats for the content\nproperty. The order describes the preferred format of the client."
+				}
+			]
+		},
+		{
+			"name": "SignatureHelpClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether signature help supports dynamic registration."
+				},
+				{
+					"name": "signatureInformation",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "documentationFormat",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "MarkupKind"
+										}
+									},
+									"optional": true,
+									"documentation": "Client supports the following content formats for the documentation\nproperty. The order describes the preferred format of the client."
+								},
+								{
+									"name": "parameterInformation",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "labelOffsetSupport",
+													"type": {
+														"kind": "base",
+														"name": "boolean"
+													},
+													"optional": true,
+													"documentation": "The client supports processing label offsets instead of a\nsimple label string.\n\n@since 3.14.0",
+													"since": "3.14.0"
+												}
+											]
+										}
+									},
+									"optional": true,
+									"documentation": "Client capabilities specific to parameter information."
+								},
+								{
+									"name": "activeParameterSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "The client supports the `activeParameter` property on `SignatureInformation`\nliteral.\n\n@since 3.16.0",
+									"since": "3.16.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client supports the following `SignatureInformation`\nspecific properties."
+				},
+				{
+					"name": "contextSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports to send additional context information for a\n`textDocument/signatureHelp` request. A client that opts into\ncontextSupport will also support the `retriggerCharacters` on\n`SignatureHelpOptions`.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"documentation": "Client Capabilities for a [SignatureHelpRequest](#SignatureHelpRequest)."
+		},
+		{
+			"name": "DeclarationClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether declaration supports dynamic registration. If this is set to `true`\nthe client supports the new `DeclarationRegistrationOptions` return value\nfor the corresponding server capability as well."
+				},
+				{
+					"name": "linkSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports additional metadata in the form of declaration links."
+				}
+			],
+			"documentation": "@since 3.14.0",
+			"since": "3.14.0"
+		},
+		{
+			"name": "DefinitionClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether definition supports dynamic registration."
+				},
+				{
+					"name": "linkSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports additional metadata in the form of definition links.\n\n@since 3.14.0",
+					"since": "3.14.0"
+				}
+			],
+			"documentation": "Client Capabilities for a [DefinitionRequest](#DefinitionRequest)."
+		},
+		{
+			"name": "TypeDefinitionClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `TypeDefinitionRegistrationOptions` return value\nfor the corresponding server capability as well."
+				},
+				{
+					"name": "linkSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports additional metadata in the form of definition links.\n\nSince 3.14.0"
+				}
+			],
+			"documentation": "Since 3.6.0"
+		},
+		{
+			"name": "ImplementationClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `ImplementationRegistrationOptions` return value\nfor the corresponding server capability as well."
+				},
+				{
+					"name": "linkSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports additional metadata in the form of definition links.\n\n@since 3.14.0",
+					"since": "3.14.0"
+				}
+			],
+			"documentation": "@since 3.6.0",
+			"since": "3.6.0"
+		},
+		{
+			"name": "ReferenceClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether references supports dynamic registration."
+				}
+			],
+			"documentation": "Client Capabilities for a [ReferencesRequest](#ReferencesRequest)."
+		},
+		{
+			"name": "DocumentHighlightClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether document highlight supports dynamic registration."
+				}
+			],
+			"documentation": "Client Capabilities for a [DocumentHighlightRequest](#DocumentHighlightRequest)."
+		},
+		{
+			"name": "DocumentSymbolClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether document symbol supports dynamic registration."
+				},
+				{
+					"name": "symbolKind",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "SymbolKind"
+										}
+									},
+									"optional": true,
+									"documentation": "The symbol kind values the client supports. When this\nproperty exists the client also guarantees that it will\nhandle values outside its set gracefully and falls back\nto a default value when unknown.\n\nIf this property is not present the client only supports\nthe symbol kinds from `File` to `Array` as defined in\nthe initial version of the protocol."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Specific capabilities for the `SymbolKind` in the\n`textDocument/documentSymbol` request."
+				},
+				{
+					"name": "hierarchicalDocumentSymbolSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports hierarchical document symbols."
+				},
+				{
+					"name": "tagSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "SymbolTag"
+										}
+									},
+									"documentation": "The tags supported by the client."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client supports tags on `SymbolInformation`. Tags are supported on\n`DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.\nClients supporting tags have to handle unknown tags gracefully.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "labelSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports an additional label presented in the UI when\nregistering a document symbol provider.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "Client Capabilities for a [DocumentSymbolRequest](#DocumentSymbolRequest)."
+		},
+		{
+			"name": "CodeActionClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code action supports dynamic registration."
+				},
+				{
+					"name": "codeActionLiteralSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "codeActionKind",
+									"type": {
+										"kind": "literal",
+										"value": {
+											"properties": [
+												{
+													"name": "valueSet",
+													"type": {
+														"kind": "array",
+														"element": {
+															"kind": "reference",
+															"name": "CodeActionKind"
+														}
+													},
+													"documentation": "The code action kind values the client supports. When this\nproperty exists the client also guarantees that it will\nhandle values outside its set gracefully and falls back\nto a default value when unknown."
+												}
+											]
+										}
+									},
+									"documentation": "The code action kind is support with the following value\nset."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "The client support code action literals of type `CodeAction` as a valid\nresponse of the `textDocument/codeAction` request. If the property is not\nset the request can only return `Command` literals.\n\n@since 3.8.0",
+					"since": "3.8.0"
+				},
+				{
+					"name": "isPreferredSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code action supports the `isPreferred` property.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "disabledSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code action supports the `disabled` property.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "dataSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code action supports the `data` property which is\npreserved between a `textDocument/codeAction` and a\n`codeAction/resolve` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "resolveSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "properties",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"documentation": "The properties that a client can resolve lazily."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Whether the client supports resolving additional code action\nproperties via a separate `codeAction/resolve` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "honorsChangeAnnotations",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client honors the change annotations in\ntext edits and resource operations returned via the\n`CodeAction#edit` property by for example presenting\nthe workspace edit in the user interface and asking\nfor confirmation.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "The Client Capabilities of a [CodeActionRequest](#CodeActionRequest)."
+		},
+		{
+			"name": "CodeLensClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code lens supports dynamic registration."
+				}
+			],
+			"documentation": "The client capabilities  of a [CodeLensRequest](#CodeLensRequest)."
+		},
+		{
+			"name": "DocumentLinkClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether document link supports dynamic registration."
+				},
+				{
+					"name": "tooltipSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client supports the `tooltip` property on `DocumentLink`.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"documentation": "The client capabilities of a [DocumentLinkRequest](#DocumentLinkRequest)."
+		},
+		{
+			"name": "DocumentColorClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `DocumentColorRegistrationOptions` return value\nfor the corresponding server capability as well."
+				}
+			]
+		},
+		{
+			"name": "DocumentFormattingClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether formatting supports dynamic registration."
+				}
+			],
+			"documentation": "Client capabilities of a [DocumentFormattingRequest](#DocumentFormattingRequest)."
+		},
+		{
+			"name": "DocumentRangeFormattingClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether range formatting supports dynamic registration."
+				}
+			],
+			"documentation": "Client capabilities of a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest)."
+		},
+		{
+			"name": "DocumentOnTypeFormattingClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether on type formatting supports dynamic registration."
+				}
+			],
+			"documentation": "Client capabilities of a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest)."
+		},
+		{
+			"name": "RenameClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether rename supports dynamic registration."
+				},
+				{
+					"name": "prepareSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Client supports testing for validity of rename operations\nbefore execution.\n\n@since 3.12.0",
+					"since": "3.12.0"
+				},
+				{
+					"name": "prepareSupportDefaultBehavior",
+					"type": {
+						"kind": "reference",
+						"name": "PrepareSupportDefaultBehavior"
+					},
+					"optional": true,
+					"documentation": "Client supports the default behavior result.\n\nThe value indicates the default behavior used by the\nclient.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "honorsChangeAnnotations",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client honors the change annotations in\ntext edits and resource operations returned via the\nrename request's workspace edit by for example presenting\nthe workspace edit in the user interface and asking\nfor confirmation.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			]
+		},
+		{
+			"name": "FoldingRangeClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration for folding range\nproviders. If this is set to `true` the client supports the new\n`FoldingRangeRegistrationOptions` return value for the corresponding\nserver capability as well."
+				},
+				{
+					"name": "rangeLimit",
+					"type": {
+						"kind": "base",
+						"name": "uinteger"
+					},
+					"optional": true,
+					"documentation": "The maximum number of folding ranges that the client prefers to receive\nper document. The value serves as a hint, servers are free to follow the\nlimit."
+				},
+				{
+					"name": "lineFoldingOnly",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "If set, the client signals that it only supports folding complete lines.\nIf set, client will ignore specified `startCharacter` and `endCharacter`\nproperties in a FoldingRange."
+				},
+				{
+					"name": "foldingRangeKind",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "FoldingRangeKind"
+										}
+									},
+									"optional": true,
+									"documentation": "The folding range kind values the client supports. When this\nproperty exists the client also guarantees that it will\nhandle values outside its set gracefully and falls back\nto a default value when unknown."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Specific options for the folding range kind.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "foldingRange",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "collapsedText",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "If set, the client signals that it supports setting collapsedText on\nfolding ranges to display custom labels instead of the default text.\n\n@since 3.17.0",
+									"since": "3.17.0"
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Specific options for the folding range.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			]
+		},
+		{
+			"name": "SelectionRangeClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration for selection range providers. If this is set to `true`\nthe client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server\ncapability as well."
+				}
+			]
+		},
+		{
+			"name": "PublishDiagnosticsClientCapabilities",
+			"properties": [
+				{
+					"name": "relatedInformation",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the clients accepts diagnostics with related information."
+				},
+				{
+					"name": "tagSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "valueSet",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "reference",
+											"name": "DiagnosticTag"
+										}
+									},
+									"documentation": "The tags supported by the client."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Client supports the tag property to provide meta data about a diagnostic.\nClients supporting tags have to handle unknown tags gracefully.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "versionSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client interprets the version property of the\n`textDocument/publishDiagnostics` notification's parameter.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				},
+				{
+					"name": "codeDescriptionSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Client supports a codeDescription property\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "dataSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether code action supports the `data` property which is\npreserved between a `textDocument/publishDiagnostics` and\n`textDocument/codeAction` request.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"documentation": "The publish diagnostic client capabilities."
+		},
+		{
+			"name": "CallHierarchyClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokensClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				},
+				{
+					"name": "requests",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "range",
+									"type": {
+										"kind": "or",
+										"items": [
+											{
+												"kind": "base",
+												"name": "boolean"
+											},
+											{
+												"kind": "literal",
+												"value": {
+													"properties": []
+												}
+											}
+										]
+									},
+									"optional": true,
+									"documentation": "The client will send the `textDocument/semanticTokens/range` request if\nthe server provides a corresponding handler."
+								},
+								{
+									"name": "full",
+									"type": {
+										"kind": "or",
+										"items": [
+											{
+												"kind": "base",
+												"name": "boolean"
+											},
+											{
+												"kind": "literal",
+												"value": {
+													"properties": [
+														{
+															"name": "delta",
+															"type": {
+																"kind": "base",
+																"name": "boolean"
+															},
+															"optional": true,
+															"documentation": "The client will send the `textDocument/semanticTokens/full/delta` request if\nthe server provides a corresponding handler."
+														}
+													]
+												}
+											}
+										]
+									},
+									"optional": true,
+									"documentation": "The client will send the `textDocument/semanticTokens/full` request if\nthe server provides a corresponding handler."
+								}
+							]
+						}
+					},
+					"documentation": "Which requests the client supports and might send to the server\ndepending on the server's capability. Please note that clients might not\nshow semantic tokens or degrade some of the user experience if a range\nor full request is advertised by the client but not provided by the\nserver. If for example the client capability `requests.full` and\n`request.range` are both set to true but the server only provides a\nrange provider the client might not render a minimap correctly or might\neven decide to not show any semantic tokens at all."
+				},
+				{
+					"name": "tokenTypes",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"documentation": "The token types that the client supports."
+				},
+				{
+					"name": "tokenModifiers",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"documentation": "The token modifiers that the client supports."
+				},
+				{
+					"name": "formats",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "TokenFormat"
+						}
+					},
+					"documentation": "The token formats the clients supports."
+				},
+				{
+					"name": "overlappingTokenSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client supports tokens that can overlap each other."
+				},
+				{
+					"name": "multilineTokenSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client supports tokens that can span multiple lines."
+				},
+				{
+					"name": "serverCancelSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client allows the server to actively cancel a\nsemantic token request, e.g. supports returning\nLSPErrorCodes.ServerCancelled. If a server does the client\nneeds to retrigger the request.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "augmentsSyntaxTokens",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the client uses semantic tokens to augment existing\nsyntax tokens. If set to `true` client side created syntax\ntokens and semantic tokens are both used for colorization. If\nset to `false` the client only uses the returned semantic tokens\nfor colorization.\n\nIf the value is `undefined` then the client behavior is not\nspecified.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "LinkedEditingRangeClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				}
+			],
+			"documentation": "Client capabilities for the linked editing range request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MonikerClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether moniker supports dynamic registration. If this is set to `true`\nthe client supports the new `MonikerRegistrationOptions` return value\nfor the corresponding server capability as well."
+				}
+			],
+			"documentation": "Client capabilities specific to the moniker request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "TypeHierarchyClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				}
+			],
+			"documentation": "@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlineValueClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration for inline value providers."
+				}
+			],
+			"documentation": "Client capabilities specific to inline values.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "InlayHintClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether inlay hints support dynamic registration."
+				},
+				{
+					"name": "resolveSupport",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "properties",
+									"type": {
+										"kind": "array",
+										"element": {
+											"kind": "base",
+											"name": "string"
+										}
+									},
+									"documentation": "The properties that a client can resolve lazily."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Indicates which properties a client can resolve lazily on an inlay\nhint."
+				}
+			],
+			"documentation": "Inlay hint client capabilities.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DiagnosticClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is set to `true`\nthe client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				},
+				{
+					"name": "relatedDocumentSupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether the clients supports related documents for document diagnostic pulls."
+				}
+			],
+			"documentation": "Client capabilities specific to diagnostic pull requests.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocumentSyncClientCapabilities",
+			"properties": [
+				{
+					"name": "dynamicRegistration",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "Whether implementation supports dynamic registration. If this is\nset to `true` the client supports the new\n`(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\nreturn value for the corresponding server capability as well."
+				},
+				{
+					"name": "executionSummarySupport",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"optional": true,
+					"documentation": "The client supports sending execution summary data per cell."
+				}
+			],
+			"documentation": "Notebook specific client capabilities.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "ShowMessageRequestClientCapabilities",
+			"properties": [
+				{
+					"name": "messageActionItem",
+					"type": {
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "additionalPropertiesSupport",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									},
+									"optional": true,
+									"documentation": "Whether the client supports additional attributes which\nare preserved and send back to the server in the\nrequest's response."
+								}
+							]
+						}
+					},
+					"optional": true,
+					"documentation": "Capabilities specific to the `MessageActionItem` type."
+				}
+			],
+			"documentation": "Show message request client capabilities"
+		},
+		{
+			"name": "ShowDocumentClientCapabilities",
+			"properties": [
+				{
+					"name": "support",
+					"type": {
+						"kind": "base",
+						"name": "boolean"
+					},
+					"documentation": "The client has support for the showDocument\nrequest."
+				}
+			],
+			"documentation": "Client capabilities for the showDocument request.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "RegularExpressionsClientCapabilities",
+			"properties": [
+				{
+					"name": "engine",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The engine's name."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The engine's version."
+				}
+			],
+			"documentation": "Client capabilities specific to regular expressions.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MarkdownClientCapabilities",
+			"properties": [
+				{
+					"name": "parser",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"documentation": "The name of the parser."
+				},
+				{
+					"name": "version",
+					"type": {
+						"kind": "base",
+						"name": "string"
+					},
+					"optional": true,
+					"documentation": "The version of the parser."
+				},
+				{
+					"name": "allowedTags",
+					"type": {
+						"kind": "array",
+						"element": {
+							"kind": "base",
+							"name": "string"
+						}
+					},
+					"optional": true,
+					"documentation": "A list of HTML tags that the client allows / supports in\nMarkdown.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "Client capabilities specific to the used markdown parser.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		}
+	],
+	"enumerations": [
+		{
+			"name": "SemanticTokenTypes",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "namespace",
+					"value": "namespace"
+				},
+				{
+					"name": "type",
+					"value": "type",
+					"documentation": "Represents a generic type. Acts as a fallback for types which can't be mapped to\na specific type like class or enum."
+				},
+				{
+					"name": "class",
+					"value": "class"
+				},
+				{
+					"name": "enum",
+					"value": "enum"
+				},
+				{
+					"name": "interface",
+					"value": "interface"
+				},
+				{
+					"name": "struct",
+					"value": "struct"
+				},
+				{
+					"name": "typeParameter",
+					"value": "typeParameter"
+				},
+				{
+					"name": "parameter",
+					"value": "parameter"
+				},
+				{
+					"name": "variable",
+					"value": "variable"
+				},
+				{
+					"name": "property",
+					"value": "property"
+				},
+				{
+					"name": "enumMember",
+					"value": "enumMember"
+				},
+				{
+					"name": "event",
+					"value": "event"
+				},
+				{
+					"name": "function",
+					"value": "function"
+				},
+				{
+					"name": "method",
+					"value": "method"
+				},
+				{
+					"name": "macro",
+					"value": "macro"
+				},
+				{
+					"name": "keyword",
+					"value": "keyword"
+				},
+				{
+					"name": "modifier",
+					"value": "modifier"
+				},
+				{
+					"name": "comment",
+					"value": "comment"
+				},
+				{
+					"name": "string",
+					"value": "string"
+				},
+				{
+					"name": "number",
+					"value": "number"
+				},
+				{
+					"name": "regexp",
+					"value": "regexp"
+				},
+				{
+					"name": "operator",
+					"value": "operator"
+				},
+				{
+					"name": "decorator",
+					"value": "decorator",
+					"documentation": "@since 3.17.0",
+					"since": "3.17.0"
+				}
+			],
+			"documentation": "A set of predefined token types. This set is not fixed\nan clients can specify additional token types via the\ncorresponding client capabilities.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "SemanticTokenModifiers",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "declaration",
+					"value": "declaration"
+				},
+				{
+					"name": "definition",
+					"value": "definition"
+				},
+				{
+					"name": "readonly",
+					"value": "readonly"
+				},
+				{
+					"name": "static",
+					"value": "static"
+				},
+				{
+					"name": "deprecated",
+					"value": "deprecated"
+				},
+				{
+					"name": "abstract",
+					"value": "abstract"
+				},
+				{
+					"name": "async",
+					"value": "async"
+				},
+				{
+					"name": "modification",
+					"value": "modification"
+				},
+				{
+					"name": "documentation",
+					"value": "documentation"
+				},
+				{
+					"name": "defaultLibrary",
+					"value": "defaultLibrary"
+				}
+			],
+			"documentation": "A set of predefined token modifiers. This set is not fixed\nan clients can specify additional token types via the\ncorresponding client capabilities.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "ErrorCodes",
+			"type": {
+				"kind": "base",
+				"name": "integer"
+			},
+			"values": [
+				{
+					"name": "ParseError",
+					"value": -32700
+				},
+				{
+					"name": "InvalidRequest",
+					"value": -32600
+				},
+				{
+					"name": "MethodNotFound",
+					"value": -32601
+				},
+				{
+					"name": "InvalidParams",
+					"value": -32602
+				},
+				{
+					"name": "InternalError",
+					"value": -32603
+				},
+				{
+					"name": "jsonrpcReservedErrorRangeStart",
+					"value": -32099,
+					"documentation": "This is the start range of JSON RPC reserved error codes.\nIt doesn't denote a real error code. No application error codes should\nbe defined between the start and end range. For backwards\ncompatibility the `ServerNotInitialized` and the `UnknownErrorCode`\nare left in the range.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "serverErrorStart",
+					"value": -32099,
+					"documentation": "@deprecated use  jsonrpcReservedErrorRangeStart */"
+				},
+				{
+					"name": "ServerNotInitialized",
+					"value": -32002,
+					"documentation": "Error code indicating that a server received a notification or\nrequest before the server has received the `initialize` request."
+				},
+				{
+					"name": "UnknownErrorCode",
+					"value": -32001
+				},
+				{
+					"name": "jsonrpcReservedErrorRangeEnd",
+					"value": -32000,
+					"documentation": "This is the end range of JSON RPC reserved error codes.\nIt doesn't denote a real error code.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "serverErrorEnd",
+					"value": -32000,
+					"documentation": "@deprecated use  jsonrpcReservedErrorRangeEnd */"
+				}
+			],
+			"supportsCustomValues": true,
+			"documentation": "Predefined error codes."
+		},
+		{
+			"name": "LSPErrorCodes",
+			"type": {
+				"kind": "base",
+				"name": "integer"
+			},
+			"values": [
+				{
+					"name": "lspReservedErrorRangeStart",
+					"value": -32899,
+					"documentation": "This is the start range of LSP reserved error codes.\nIt doesn't denote a real error code.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				},
+				{
+					"name": "RequestFailed",
+					"value": -32803,
+					"documentation": "A request failed but it was syntactically correct, e.g the\nmethod name was known and the parameters were valid. The error\nmessage should contain human readable information about why\nthe request failed.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "ServerCancelled",
+					"value": -32802,
+					"documentation": "The server cancelled the request. This error code should\nonly be used for requests that explicitly support being\nserver cancellable.\n\n@since 3.17.0",
+					"since": "3.17.0"
+				},
+				{
+					"name": "ContentModified",
+					"value": -32801,
+					"documentation": "The server detected that the content of a document got\nmodified outside normal conditions. A server should\nNOT send this error code if it detects a content change\nin it unprocessed messages. The result even computed\non an older state might still be useful for the client.\n\nIf a client decides that a result is not of any use anymore\nthe client should cancel the request."
+				},
+				{
+					"name": "RequestCancelled",
+					"value": -32800,
+					"documentation": "The client has canceled a request and a server as detected\nthe cancel."
+				},
+				{
+					"name": "lspReservedErrorRangeEnd",
+					"value": -32800,
+					"documentation": "This is the end range of LSP reserved error codes.\nIt doesn't denote a real error code.\n\n@since 3.16.0",
+					"since": "3.16.0"
+				}
+			],
+			"supportsCustomValues": true
+		},
+		{
+			"name": "FoldingRangeKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Comment",
+					"value": "comment",
+					"documentation": "Folding range for a comment"
+				},
+				{
+					"name": "Imports",
+					"value": "imports",
+					"documentation": "Folding range for an import or include"
+				},
+				{
+					"name": "Region",
+					"value": "region",
+					"documentation": "Folding range for a region (e.g. `#region`)"
+				}
+			],
+			"supportsCustomValues": true,
+			"documentation": "A set of predefined range kinds."
+		},
+		{
+			"name": "SymbolKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "File",
+					"value": 1
+				},
+				{
+					"name": "Module",
+					"value": 2
+				},
+				{
+					"name": "Namespace",
+					"value": 3
+				},
+				{
+					"name": "Package",
+					"value": 4
+				},
+				{
+					"name": "Class",
+					"value": 5
+				},
+				{
+					"name": "Method",
+					"value": 6
+				},
+				{
+					"name": "Property",
+					"value": 7
+				},
+				{
+					"name": "Field",
+					"value": 8
+				},
+				{
+					"name": "Constructor",
+					"value": 9
+				},
+				{
+					"name": "Enum",
+					"value": 10
+				},
+				{
+					"name": "Interface",
+					"value": 11
+				},
+				{
+					"name": "Function",
+					"value": 12
+				},
+				{
+					"name": "Variable",
+					"value": 13
+				},
+				{
+					"name": "Constant",
+					"value": 14
+				},
+				{
+					"name": "String",
+					"value": 15
+				},
+				{
+					"name": "Number",
+					"value": 16
+				},
+				{
+					"name": "Boolean",
+					"value": 17
+				},
+				{
+					"name": "Array",
+					"value": 18
+				},
+				{
+					"name": "Object",
+					"value": 19
+				},
+				{
+					"name": "Key",
+					"value": 20
+				},
+				{
+					"name": "Null",
+					"value": 21
+				},
+				{
+					"name": "EnumMember",
+					"value": 22
+				},
+				{
+					"name": "Struct",
+					"value": 23
+				},
+				{
+					"name": "Event",
+					"value": 24
+				},
+				{
+					"name": "Operator",
+					"value": 25
+				},
+				{
+					"name": "TypeParameter",
+					"value": 26
+				}
+			],
+			"documentation": "A symbol kind."
+		},
+		{
+			"name": "SymbolTag",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Deprecated",
+					"value": 1,
+					"documentation": "Render a symbol as obsolete, usually using a strike-out."
+				}
+			],
+			"documentation": "Symbol tags are extra annotations that tweak the rendering of a symbol.\n\n@since 3.16",
+			"since": "3.16"
+		},
+		{
+			"name": "UniquenessLevel",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "document",
+					"value": "document",
+					"documentation": "The moniker is only unique inside a document"
+				},
+				{
+					"name": "project",
+					"value": "project",
+					"documentation": "The moniker is unique inside a project for which a dump got created"
+				},
+				{
+					"name": "group",
+					"value": "group",
+					"documentation": "The moniker is unique inside the group to which a project belongs"
+				},
+				{
+					"name": "scheme",
+					"value": "scheme",
+					"documentation": "The moniker is unique inside the moniker scheme."
+				},
+				{
+					"name": "global",
+					"value": "global",
+					"documentation": "The moniker is globally unique"
+				}
+			],
+			"documentation": "Moniker uniqueness level to define scope of the moniker.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "MonikerKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "import",
+					"value": "import",
+					"documentation": "The moniker represent a symbol that is imported into a project"
+				},
+				{
+					"name": "export",
+					"value": "export",
+					"documentation": "The moniker represents a symbol that is exported from a project"
+				},
+				{
+					"name": "local",
+					"value": "local",
+					"documentation": "The moniker represents a symbol that is local to a project (e.g. a local\nvariable of a function, a class not visible outside the project, ...)"
+				}
+			],
+			"documentation": "The moniker kind.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "InlayHintKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Type",
+					"value": 1,
+					"documentation": "An inlay hint that for a type annotation."
+				},
+				{
+					"name": "Parameter",
+					"value": 2,
+					"documentation": "An inlay hint that is for a parameter."
+				}
+			],
+			"documentation": "Inlay hint kinds.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "MessageType",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Error",
+					"value": 1,
+					"documentation": "An error message."
+				},
+				{
+					"name": "Warning",
+					"value": 2,
+					"documentation": "A warning message."
+				},
+				{
+					"name": "Info",
+					"value": 3,
+					"documentation": "An information message."
+				},
+				{
+					"name": "Log",
+					"value": 4,
+					"documentation": "A log message."
+				}
+			],
+			"documentation": "The message type"
+		},
+		{
+			"name": "TextDocumentSyncKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "None",
+					"value": 0,
+					"documentation": "Documents should not be synced at all."
+				},
+				{
+					"name": "Full",
+					"value": 1,
+					"documentation": "Documents are synced by always sending the full content\nof the document."
+				},
+				{
+					"name": "Incremental",
+					"value": 2,
+					"documentation": "Documents are synced by sending the full content on open.\nAfter that only incremental updates to the document are\nsend."
+				}
+			],
+			"documentation": "Defines how the host (editor) should sync\ndocument changes to the language server."
+		},
+		{
+			"name": "TextDocumentSaveReason",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Manual",
+					"value": 1,
+					"documentation": "Manually triggered, e.g. by the user pressing save, by starting debugging,\nor by an API call."
+				},
+				{
+					"name": "AfterDelay",
+					"value": 2,
+					"documentation": "Automatic after a delay."
+				},
+				{
+					"name": "FocusOut",
+					"value": 3,
+					"documentation": "When the editor lost focus."
+				}
+			],
+			"documentation": "Represents reasons why a text document is saved."
+		},
+		{
+			"name": "CompletionItemKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Text",
+					"value": 1
+				},
+				{
+					"name": "Method",
+					"value": 2
+				},
+				{
+					"name": "Function",
+					"value": 3
+				},
+				{
+					"name": "Constructor",
+					"value": 4
+				},
+				{
+					"name": "Field",
+					"value": 5
+				},
+				{
+					"name": "Variable",
+					"value": 6
+				},
+				{
+					"name": "Class",
+					"value": 7
+				},
+				{
+					"name": "Interface",
+					"value": 8
+				},
+				{
+					"name": "Module",
+					"value": 9
+				},
+				{
+					"name": "Property",
+					"value": 10
+				},
+				{
+					"name": "Unit",
+					"value": 11
+				},
+				{
+					"name": "Value",
+					"value": 12
+				},
+				{
+					"name": "Enum",
+					"value": 13
+				},
+				{
+					"name": "Keyword",
+					"value": 14
+				},
+				{
+					"name": "Snippet",
+					"value": 15
+				},
+				{
+					"name": "Color",
+					"value": 16
+				},
+				{
+					"name": "File",
+					"value": 17
+				},
+				{
+					"name": "Reference",
+					"value": 18
+				},
+				{
+					"name": "Folder",
+					"value": 19
+				},
+				{
+					"name": "EnumMember",
+					"value": 20
+				},
+				{
+					"name": "Constant",
+					"value": 21
+				},
+				{
+					"name": "Struct",
+					"value": 22
+				},
+				{
+					"name": "Event",
+					"value": 23
+				},
+				{
+					"name": "Operator",
+					"value": 24
+				},
+				{
+					"name": "TypeParameter",
+					"value": 25
+				}
+			],
+			"documentation": "The kind of a completion entry."
+		},
+		{
+			"name": "CompletionItemTag",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Deprecated",
+					"value": 1,
+					"documentation": "Render a completion as obsolete, usually using a strike-out."
+				}
+			],
+			"documentation": "Completion item tags are extra annotations that tweak the rendering of a completion\nitem.\n\n@since 3.15.0",
+			"since": "3.15.0"
+		},
+		{
+			"name": "InsertTextFormat",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "PlainText",
+					"value": 1,
+					"documentation": "The primary text to be inserted is treated as a plain string."
+				},
+				{
+					"name": "Snippet",
+					"value": 2,
+					"documentation": "The primary text to be inserted is treated as a snippet.\n\nA snippet can define tab stops and placeholders with `$1`, `$2`\nand `${3:foo}`. `$0` defines the final tab stop, it defaults to\nthe end of the snippet. Placeholders with equal identifiers are linked,\nthat is typing in one will update others too.\n\nSee also: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax"
+				}
+			],
+			"documentation": "Defines whether the insert text in a completion item should be interpreted as\nplain text or a snippet."
+		},
+		{
+			"name": "InsertTextMode",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "asIs",
+					"value": 1,
+					"documentation": "The insertion or replace strings is taken as it is. If the\nvalue is multi line the lines below the cursor will be\ninserted using the indentation defined in the string value.\nThe client will not apply any kind of adjustments to the\nstring."
+				},
+				{
+					"name": "adjustIndentation",
+					"value": 2,
+					"documentation": "The editor adjusts leading whitespace of new lines so that\nthey match the indentation up to the cursor of the line for\nwhich the item is accepted.\n\nConsider a line like this: <2tabs><cursor><3tabs>foo. Accepting a\nmulti line completion item is indented using 2 tabs and all\nfollowing lines inserted will be indented using 2 tabs as well."
+				}
+			],
+			"documentation": "How whitespace and indentation is handled during completion\nitem insertion.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "DocumentHighlightKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Text",
+					"value": 1,
+					"documentation": "A textual occurrence."
+				},
+				{
+					"name": "Read",
+					"value": 2,
+					"documentation": "Read-access of a symbol, like reading a variable."
+				},
+				{
+					"name": "Write",
+					"value": 3,
+					"documentation": "Write-access of a symbol, like writing to a variable."
+				}
+			],
+			"documentation": "A document highlight kind."
+		},
+		{
+			"name": "CodeActionKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Empty",
+					"value": "",
+					"documentation": "Empty kind."
+				},
+				{
+					"name": "QuickFix",
+					"value": "quickfix",
+					"documentation": "Base kind for quickfix actions: 'quickfix'"
+				},
+				{
+					"name": "Refactor",
+					"value": "refactor",
+					"documentation": "Base kind for refactoring actions: 'refactor'"
+				},
+				{
+					"name": "RefactorExtract",
+					"value": "refactor.extract",
+					"documentation": "Base kind for refactoring extraction actions: 'refactor.extract'\n\nExample extract actions:\n\n- Extract method\n- Extract function\n- Extract variable\n- Extract interface from class\n- ..."
+				},
+				{
+					"name": "RefactorInline",
+					"value": "refactor.inline",
+					"documentation": "Base kind for refactoring inline actions: 'refactor.inline'\n\nExample inline actions:\n\n- Inline function\n- Inline variable\n- Inline constant\n- ..."
+				},
+				{
+					"name": "RefactorRewrite",
+					"value": "refactor.rewrite",
+					"documentation": "Base kind for refactoring rewrite actions: 'refactor.rewrite'\n\nExample rewrite actions:\n\n- Convert JavaScript function to class\n- Add or remove parameter\n- Encapsulate field\n- Make method static\n- Move method to base class\n- ..."
+				},
+				{
+					"name": "Source",
+					"value": "source",
+					"documentation": "Base kind for source actions: `source`\n\nSource code actions apply to the entire file."
+				},
+				{
+					"name": "SourceOrganizeImports",
+					"value": "source.organizeImports",
+					"documentation": "Base kind for an organize imports source action: `source.organizeImports`"
+				},
+				{
+					"name": "SourceFixAll",
+					"value": "source.fixAll",
+					"documentation": "Base kind for auto-fix source actions: `source.fixAll`.\n\nFix all actions automatically fix errors that have a clear fix that do not require user input.\nThey should not suppress errors or perform unsafe fixes such as generating new types or classes.\n\n@since 3.15.0",
+					"since": "3.15.0"
+				}
+			],
+			"supportsCustomValues": true,
+			"documentation": "A set of predefined code action kinds"
+		},
+		{
+			"name": "TraceValues",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Off",
+					"value": "off",
+					"documentation": "Turn tracing off."
+				},
+				{
+					"name": "Messages",
+					"value": "messages",
+					"documentation": "Trace messages only."
+				},
+				{
+					"name": "Verbose",
+					"value": "verbose",
+					"documentation": "Verbose message tracing."
+				}
+			]
+		},
+		{
+			"name": "MarkupKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "PlainText",
+					"value": "plaintext",
+					"documentation": "Plain text is supported as a content format"
+				},
+				{
+					"name": "Markdown",
+					"value": "markdown",
+					"documentation": "Markdown is supported as a content format"
+				}
+			],
+			"documentation": "Describes the content type that a client supports in various\nresult literals like `Hover`, `ParameterInfo` or `CompletionItem`.\n\nPlease note that `MarkupKinds` must not start with a `$`. This kinds\nare reserved for internal usage."
+		},
+		{
+			"name": "PositionEncodingKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "UTF8",
+					"value": "utf-8",
+					"documentation": "Character offsets count UTF-8 code units."
+				},
+				{
+					"name": "UTF16",
+					"value": "utf-16",
+					"documentation": "Character offsets count UTF-16 code units.\n\nThis is the default and must always be supported\nby servers"
+				},
+				{
+					"name": "UTF32",
+					"value": "utf-32",
+					"documentation": "Character offsets count UTF-32 code units.\n\nImplementation note: these are the same as Unicode code points,\nso this `PositionEncodingKind` may also be used for an\nencoding-agnostic representation of character offsets."
+				}
+			],
+			"supportsCustomValues": true,
+			"documentation": "A set of predefined position encoding kinds.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "FileChangeType",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Created",
+					"value": 1,
+					"documentation": "The file got created."
+				},
+				{
+					"name": "Changed",
+					"value": 2,
+					"documentation": "The file got changed."
+				},
+				{
+					"name": "Deleted",
+					"value": 3,
+					"documentation": "The file got deleted."
+				}
+			],
+			"documentation": "The file event type"
+		},
+		{
+			"name": "WatchKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Create",
+					"value": 1,
+					"documentation": "Interested in create events."
+				},
+				{
+					"name": "Change",
+					"value": 2,
+					"documentation": "Interested in change events"
+				},
+				{
+					"name": "Delete",
+					"value": 4,
+					"documentation": "Interested in delete events"
+				}
+			],
+			"supportsCustomValues": true
+		},
+		{
+			"name": "DiagnosticSeverity",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Error",
+					"value": 1,
+					"documentation": "Reports an error."
+				},
+				{
+					"name": "Warning",
+					"value": 2,
+					"documentation": "Reports a warning."
+				},
+				{
+					"name": "Information",
+					"value": 3,
+					"documentation": "Reports an information."
+				},
+				{
+					"name": "Hint",
+					"value": 4,
+					"documentation": "Reports a hint."
+				}
+			],
+			"documentation": "The diagnostic's severity."
+		},
+		{
+			"name": "DiagnosticTag",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Unnecessary",
+					"value": 1,
+					"documentation": "Unused or unnecessary code.\n\nClients are allowed to render diagnostics with this tag faded out instead of having\nan error squiggle."
+				},
+				{
+					"name": "Deprecated",
+					"value": 2,
+					"documentation": "Deprecated or obsolete code.\n\nClients are allowed to rendered diagnostics with this tag strike through."
+				}
+			],
+			"documentation": "The diagnostic tags.\n\n@since 3.15.0",
+			"since": "3.15.0"
+		},
+		{
+			"name": "CompletionTriggerKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Invoked",
+					"value": 1,
+					"documentation": "Completion was triggered by typing an identifier (24x7 code\ncomplete), manual invocation (e.g Ctrl+Space) or via API."
+				},
+				{
+					"name": "TriggerCharacter",
+					"value": 2,
+					"documentation": "Completion was triggered by a trigger character specified by\nthe `triggerCharacters` properties of the `CompletionRegistrationOptions`."
+				},
+				{
+					"name": "TriggerForIncompleteCompletions",
+					"value": 3,
+					"documentation": "Completion was re-triggered as current completion list is incomplete"
+				}
+			],
+			"documentation": "How a completion was triggered"
+		},
+		{
+			"name": "SignatureHelpTriggerKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Invoked",
+					"value": 1,
+					"documentation": "Signature help was invoked manually by the user or by a command."
+				},
+				{
+					"name": "TriggerCharacter",
+					"value": 2,
+					"documentation": "Signature help was triggered by a trigger character."
+				},
+				{
+					"name": "ContentChange",
+					"value": 3,
+					"documentation": "Signature help was triggered by the cursor moving or by the document content changing."
+				}
+			],
+			"documentation": "How a signature help was triggered.\n\n@since 3.15.0",
+			"since": "3.15.0"
+		},
+		{
+			"name": "CodeActionTriggerKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Invoked",
+					"value": 1,
+					"documentation": "Code actions were explicitly requested by the user or by an extension."
+				},
+				{
+					"name": "Automatic",
+					"value": 2,
+					"documentation": "Code actions were requested automatically.\n\nThis typically happens when current selection in a file changes, but can\nalso be triggered when file content changes."
+				}
+			],
+			"documentation": "The reason why code actions were requested.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "FileOperationPatternKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "file",
+					"value": "file",
+					"documentation": "The pattern matches a file only."
+				},
+				{
+					"name": "folder",
+					"value": "folder",
+					"documentation": "The pattern matches a folder only."
+				}
+			],
+			"documentation": "A pattern kind describing if a glob pattern matches a file a folder or\nboth.\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "NotebookCellKind",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Markup",
+					"value": 1,
+					"documentation": "A markup-cell is formatted source that is used for display."
+				},
+				{
+					"name": "Code",
+					"value": 2,
+					"documentation": "A code-cell is source code."
+				}
+			],
+			"documentation": "A notebook cell kind.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "ResourceOperationKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Create",
+					"value": "create",
+					"documentation": "Supports creating new files and folders."
+				},
+				{
+					"name": "Rename",
+					"value": "rename",
+					"documentation": "Supports renaming existing files and folders."
+				},
+				{
+					"name": "Delete",
+					"value": "delete",
+					"documentation": "Supports deleting existing files and folders."
+				}
+			]
+		},
+		{
+			"name": "FailureHandlingKind",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Abort",
+					"value": "abort",
+					"documentation": "Applying the workspace change is simply aborted if one of the changes provided\nfails. All operations executed before the failing operation stay executed."
+				},
+				{
+					"name": "Transactional",
+					"value": "transactional",
+					"documentation": "All operations are executed transactional. That means they either all\nsucceed or no changes at all are applied to the workspace."
+				},
+				{
+					"name": "TextOnlyTransactional",
+					"value": "textOnlyTransactional",
+					"documentation": "If the workspace edit contains only textual file changes they are executed transactional.\nIf resource changes (create, rename or delete file) are part of the change the failure\nhandling strategy is abort."
+				},
+				{
+					"name": "Undo",
+					"value": "undo",
+					"documentation": "The client tries to undo the operations already executed. But there is no\nguarantee that this is succeeding."
+				}
+			]
+		},
+		{
+			"name": "PrepareSupportDefaultBehavior",
+			"type": {
+				"kind": "base",
+				"name": "uinteger"
+			},
+			"values": [
+				{
+					"name": "Identifier",
+					"value": 1,
+					"documentation": "The client's default behavior is to select the identifier\naccording the to language's syntax rule."
+				}
+			]
+		},
+		{
+			"name": "TokenFormat",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"values": [
+				{
+					"name": "Relative",
+					"value": "relative"
+				}
+			]
+		}
+	],
+	"typeAliases": [
+		{
+			"name": "Definition",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Location"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					}
+				]
+			},
+			"documentation": "The definition of a symbol represented as one or many [locations](#Location).\nFor most programming languages there is only one location at which a symbol is\ndefined.\n\nServers should prefer returning `DefinitionLink` over `Definition` if supported\nby the client."
+		},
+		{
+			"name": "DefinitionLink",
+			"type": {
+				"kind": "reference",
+				"name": "LocationLink"
+			},
+			"documentation": "Information about where a symbol is defined.\n\nProvides additional metadata over normal [location](#Location) definitions, including the range of\nthe defining symbol"
+		},
+		{
+			"name": "LSPArray",
+			"type": {
+				"kind": "array",
+				"element": {
+					"kind": "reference",
+					"name": "LSPAny"
+				}
+			},
+			"documentation": "LSP arrays.\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "LSPAny",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "LSPObject"
+					},
+					{
+						"kind": "reference",
+						"name": "LSPArray"
+					},
+					{
+						"kind": "base",
+						"name": "string"
+					},
+					{
+						"kind": "base",
+						"name": "integer"
+					},
+					{
+						"kind": "base",
+						"name": "uinteger"
+					},
+					{
+						"kind": "base",
+						"name": "decimal"
+					},
+					{
+						"kind": "base",
+						"name": "boolean"
+					},
+					{
+						"kind": "base",
+						"name": "null"
+					}
+				]
+			},
+			"documentation": "The LSP any type.\nPlease note that strictly speaking a property with the value `undefined`\ncan't be converted into JSON preserving the property name. However for\nconvenience it is allowed and assumed that all these properties are\noptional as well.\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "Declaration",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Location"
+					},
+					{
+						"kind": "array",
+						"element": {
+							"kind": "reference",
+							"name": "Location"
+						}
+					}
+				]
+			},
+			"documentation": "The declaration of a symbol representation as one or many [locations](#Location)."
+		},
+		{
+			"name": "DeclarationLink",
+			"type": {
+				"kind": "reference",
+				"name": "LocationLink"
+			},
+			"documentation": "Information about where a symbol is declared.\n\nProvides additional metadata over normal [location](#Location) declarations, including the range of\nthe declaring symbol.\n\nServers should prefer returning `DeclarationLink` over `Declaration` if supported\nby the client."
+		},
+		{
+			"name": "InlineValue",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "InlineValueText"
+					},
+					{
+						"kind": "reference",
+						"name": "InlineValueVariableLookup"
+					},
+					{
+						"kind": "reference",
+						"name": "InlineValueEvaluatableExpression"
+					}
+				]
+			},
+			"documentation": "Inline value information can be provided by different means:\n- directly as a text value (class InlineValueText).\n- as a name to use for a variable lookup (class InlineValueVariableLookup)\n- as an evaluatable expression (class InlineValueEvaluatableExpression)\nThe InlineValue types combines all inline value types into one type.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "DocumentDiagnosticReport",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "RelatedFullDocumentDiagnosticReport"
+					},
+					{
+						"kind": "reference",
+						"name": "RelatedUnchangedDocumentDiagnosticReport"
+					}
+				]
+			},
+			"documentation": "The result of a document diagnostic pull request. A report can\neither be a full report containing all diagnostics for the\nrequested document or an unchanged report indicating that nothing\nhas changed in terms of diagnostics in comparison to the last\npull request.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "PrepareRenameResult",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Range"
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "range",
+									"type": {
+										"kind": "reference",
+										"name": "Range"
+									}
+								},
+								{
+									"name": "placeholder",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									}
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "defaultBehavior",
+									"type": {
+										"kind": "base",
+										"name": "boolean"
+									}
+								}
+							]
+						}
+					}
+				]
+			}
+		},
+		{
+			"name": "URI",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"documentation": "A tagging type for string properties that are actually URIs\n\n@since 3.16.0",
+			"since": "3.16.0"
+		},
+		{
+			"name": "ProgressToken",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "base",
+						"name": "integer"
+					},
+					{
+						"kind": "base",
+						"name": "string"
+					}
+				]
+			}
+		},
+		{
+			"name": "DocumentSelector",
+			"type": {
+				"kind": "array",
+				"element": {
+					"kind": "or",
+					"items": [
+						{
+							"kind": "base",
+							"name": "string"
+						},
+						{
+							"kind": "reference",
+							"name": "DocumentFilter"
+						}
+					]
+				}
+			},
+			"documentation": "A document selector is the combination of one or many document filters.\n\n@sample `let sel:DocumentSelector = [{ language: 'typescript' }, { language: 'json', pattern: '**∕tsconfig.json' }]`;\n\nThe use of a string as a document filter is deprecated @since 3.16.0.",
+			"since": "3.16.0."
+		},
+		{
+			"name": "ChangeAnnotationIdentifier",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"documentation": "An identifier to refer to a change annotation stored with a workspace edit."
+		},
+		{
+			"name": "WorkspaceDocumentDiagnosticReport",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "WorkspaceFullDocumentDiagnosticReport"
+					},
+					{
+						"kind": "reference",
+						"name": "WorkspaceUnchangedDocumentDiagnosticReport"
+					}
+				]
+			},
+			"documentation": "A workspace diagnostic document report.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TextDocumentContentChangeEvent",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "range",
+									"type": {
+										"kind": "reference",
+										"name": "Range"
+									},
+									"documentation": "The range of the document that changed."
+								},
+								{
+									"name": "rangeLength",
+									"type": {
+										"kind": "base",
+										"name": "uinteger"
+									},
+									"optional": true,
+									"documentation": "The optional length of the range that got replaced.\n\n@deprecated use range instead."
+								},
+								{
+									"name": "text",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "The new text for the provided range."
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "text",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "The new text of the whole document."
+								}
+							]
+						}
+					}
+				]
+			},
+			"documentation": "An event describing a change to a text document. If only a text is provided\nit is considered to be the full content of the document."
+		},
+		{
+			"name": "MarkedString",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "base",
+						"name": "string"
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "language",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									}
+								},
+								{
+									"name": "value",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									}
+								}
+							]
+						}
+					}
+				]
+			},
+			"documentation": "MarkedString can be used to render human readable text. It is either a markdown string\nor a code-block that provides a language and a code snippet. The language identifier\nis semantically equal to the optional language identifier in fenced code blocks in GitHub\nissues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting\n\nThe pair of a language and a value is an equivalent to markdown:\n```${language}\n${value}\n```\n\nNote that markdown strings will be sanitized - that means html will be escaped.\n@deprecated use MarkupContent instead."
+		},
+		{
+			"name": "DocumentFilter",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "TextDocumentFilter"
+					},
+					{
+						"kind": "reference",
+						"name": "NotebookCellTextDocumentFilter"
+					}
+				]
+			},
+			"documentation": "A document filter describes a top level text document or\na notebook cell document.\n\n@since 3.17.0 - proposed support for NotebookCellTextDocumentFilter.",
+			"since": "3.17.0 - proposed support for NotebookCellTextDocumentFilter."
+		},
+		{
+			"name": "GlobPattern",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "reference",
+						"name": "Pattern"
+					},
+					{
+						"kind": "reference",
+						"name": "RelativePattern"
+					}
+				]
+			},
+			"documentation": "The glob pattern. Either a string pattern or a relative pattern.\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "TextDocumentFilter",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "language",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "A language id, like `typescript`. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A glob pattern, like `*.{ts,js}`. */"
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "language",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A language id, like `typescript`. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A glob pattern, like `*.{ts,js}`. */"
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "language",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A language id, like `typescript`. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "A glob pattern, like `*.{ts,js}`. */"
+								}
+							]
+						}
+					}
+				]
+			},
+			"documentation": "A document filter denotes a document by different properties like\nthe [language](#TextDocument.languageId), the [scheme](#Uri.scheme) of\nits resource, or a glob-pattern that is applied to the [path](#TextDocument.fileName).\n\nGlob patterns can have the following syntax:\n- `*` to match one or more characters in a path segment\n- `?` to match on one character in a path segment\n- `**` to match any number of path segments, including none\n- `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)\n- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n- `[!...]` 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`)\n\n@sample A language filter that applies to typescript files on disk: `{ language: 'typescript', scheme: 'file' }`\n@sample A language filter that applies to all package.json paths: `{ language: 'json', pattern: '**package.json' }`\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "NotebookDocumentFilter",
+			"type": {
+				"kind": "or",
+				"items": [
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "notebookType",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "The type of the enclosing notebook. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A glob pattern. */"
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "notebookType",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "The type of the enclosing notebook. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`.*/"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A glob pattern. */"
+								}
+							]
+						}
+					},
+					{
+						"kind": "literal",
+						"value": {
+							"properties": [
+								{
+									"name": "notebookType",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "The type of the enclosing notebook. */"
+								},
+								{
+									"name": "scheme",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"optional": true,
+									"documentation": "A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */"
+								},
+								{
+									"name": "pattern",
+									"type": {
+										"kind": "base",
+										"name": "string"
+									},
+									"documentation": "A glob pattern. */"
+								}
+							]
+						}
+					}
+				]
+			},
+			"documentation": "A notebook document filter denotes a notebook document by\ndifferent properties. The properties will be match\nagainst the notebook's URI (same as with documents)\n\n@since 3.17.0",
+			"since": "3.17.0"
+		},
+		{
+			"name": "Pattern",
+			"type": {
+				"kind": "base",
+				"name": "string"
+			},
+			"documentation": "The glob pattern to watch relative to the base path. Glob patterns can have the following syntax:\n- `*` to match one or more characters in a path segment\n- `?` to match on one character in a path segment\n- `**` to match any number of path segments, including none\n- `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)\n- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n- `[!...]` 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`)\n\n@since 3.17.0",
+			"since": "3.17.0"
+		}
+	]
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.license.txt b/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.license.txt
new file mode 100644
index 0000000..3ef1f41
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/lsp_meta_model.license.txt
@@ -0,0 +1,15 @@
+This license is for the lsp_meta_model.json file.
+
+lsp_meta_model.license.txt downloaded from: https://microsoft.github.io/language-server-protocol/License.txt
+lsp_meta_model.json downloaded from: https://raw.githubusercontent.com/microsoft/vscode-languageserver-node/main/protocol/metaModel.json
+
+--
+
+Copyright (c) Microsoft Corporation.

+ 

+All rights reserved. 

+

+Distributed under the following terms:

+

+1.	Documentation is licensed under the Creative Commons Attribution 3.0 United States License. Code is licensed under the MIT License.

+2. This license does not grant you rights to use any trademarks or logos of Microsoft. For Microsoft’s general trademark guidelines, go to http://go.microsoft.com/fwlink/?LinkID=254653
\ No newline at end of file
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
deleted file mode 100644
index 5bee93f..0000000
--- a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
+++ /dev/null
@@ -1,11645 +0,0 @@
-This is an unmodified copy of the Language Server Protocol Specification,
-downloaded from https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/lsp/3.17/specification.md. It is the version of the specification that was
-used to generate a portion of the Dart code used to support the protocol.
-
-To regenerate the generated code, run the script in
-"analysis_server/tool/lsp_spec/generate_all.dart" with no arguments. To
-download the latest version of the specification before regenerating the
-code, run the same script with an argument of "--download".
-
----
-
-Copyright (c) Microsoft Corporation.
- 
-All rights reserved. 
-
-Distributed under the following terms:
-
-1.	Documentation is licensed under the Creative Commons Attribution 3.0 United States License. Code is licensed under the MIT License.
-2. This license does not grant you rights to use any trademarks or logos of Microsoft. For Microsoft’s general trademark guidelines, go to http://go.microsoft.com/fwlink/?LinkID=254653
-
----
-
----
-title: Specification
-shortTitle: 3.17 (Upcoming)
-layout: specifications
-sectionid: specification-3-17
-toc: specification-3-17-toc
-fullTitle: Language Server Protocol Specification - 3.17
-index: 2
-redirect_from:
-  - specification
-  - specification/
-  - specifications/specification-current
-  - specifications/specification-current/
----
-
-This document describes the 3.17.x version of the language server protocol. An implementation for node of the 3.17.x version of the protocol can be found [here](https://github.com/Microsoft/vscode-languageserver-node).
-
-**Note:** edits to this specification can be made via a pull request against this markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/lsp/3.17/specification.md).
-
-## <a href="#whatIsNew" name="whatIsNew" class="anchor"> What's new in 3.17 </a>
-
-All new 3.17 features are tagged with a corresponding since version 3.17 text or in JSDoc using `@since 3.17.0` annotation. Major new feature are: type hierarchy, inline values, inlay hints, notebook document support and a meta model that describes the 3.17 LSP version.
-
-A detailed list of the changes can be found in the [change log](#version_3_17_0)
-
-The version of the specification is used to group features into a new specification release and to refer to their first appearance. Features in the spec are kept compatible using so called capability flags which are exchanged between the client and the server during initialization.
-
-## <a href="#baseProtocol" name="baseProtocol" class="anchor"> Base Protocol </a>
-
-The base protocol consists of a header and a content part (comparable to HTTP). The header and content part are
-separated by a '\r\n'.
-
-### <a href="#headerPart" name="headerPart" class="anchor"> Header Part </a>
-
-The header part consists of header fields. Each header field is comprised of a name and a value, separated by ': ' (a colon and a space). The structure of header fields conform to the [HTTP semantic](https://tools.ietf.org/html/rfc7230#section-3.2). Each header field is terminated by '\r\n'. Considering the last header field and the overall header itself are each terminated with '\r\n', and that at least one header is mandatory, this means that two '\r\n' sequences always immediately precede the content part of a message.
-
-Currently the following header fields are supported:
-
-| Header Field Name | Value Type  | Description |
-|:------------------|:------------|:------------|
-| Content-Length    | number      | The length of the content part in bytes. This header is required. |
-| Content-Type      | string      | The mime type of the content part. Defaults to application/vscode-jsonrpc; charset=utf-8 |
-{: .table .table-bordered .table-responsive}
-
-The header part is encoded using the 'ascii' encoding. This includes the '\r\n' separating the header and content part.
-
-### <a href="#contentPart" name="contentPart" class="anchor"> Content Part </a>
-
-Contains the actual content of the message. The content part of a message uses [JSON-RPC](http://www.jsonrpc.org/) to describe requests, responses and notifications. The content part is encoded using the charset provided in the Content-Type field. It defaults to `utf-8`, which is the only encoding supported right now. If a server or client receives a header with a different encoding than `utf-8` it should respond with an error.
-
-(Prior versions of the protocol used the string constant `utf8` which is not a correct encoding constant according to [specification](http://www.iana.org/assignments/character-sets/character-sets.xhtml).) For backwards compatibility it is highly recommended that a client and a server treats the string `utf8` as `utf-8`.
-
-### Example:
-
-```
-Content-Length: ...\r\n
-\r\n
-{
-	"jsonrpc": "2.0",
-	"id": 1,
-	"method": "textDocument/didOpen",
-	"params": {
-		...
-	}
-}
-```
-### Base Protocol JSON structures
-
-The following TypeScript definitions describe the base [JSON-RPC protocol](http://www.jsonrpc.org/specification):
-
-#### <a href="#baseTypes" name="baseTypes" class="anchor"> Base Types </a>
-
-The protocol use the following definitions for integers, unsigned integers, decimal numbers, objects and arrays:
-
-<div class="anchorHolder"><a href="#integer" name="integer" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines an integer number in the range of -2^31 to 2^31 - 1.
- */
-export type integer = number;
-```
-
-<div class="anchorHolder"><a href="#uinteger" name="uinteger" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines an unsigned integer number in the range of 0 to 2^31 - 1.
- */
-export type uinteger = number;
-```
-
-<div class="anchorHolder"><a href="#decimal" name="decimal" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines a decimal number. Since decimal numbers are very
- * rare in the language server specification we denote the
- * exact range with every decimal using the mathematics
- * interval notation (e.g. [0, 1] denotes all decimals d with
- * 0 <= d <= 1.
- */
-export type decimal = number;
-```
-
-<div class="anchorHolder"><a href="#lspAny" name="lspAny" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The LSP any type
- *
- * @since 3.17.0
- */
-export type LSPAny = LSPObject | LSPArray | string | integer | uinteger |
-	decimal | boolean | null;
-```
-
-<div class="anchorHolder"><a href="#lspObject" name="lspObject" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * LSP object definition.
- *
- * @since 3.17.0
- */
-export type LSPObject = { [key: string]: LSPAny };
-```
-
-<div class="anchorHolder"><a href="#lspArray" name="lspArray" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * LSP arrays.
- *
- * @since 3.17.0
- */
-export type LSPArray = LSPAny[];
-```
-
-#### <a href="#abstractMessage" name="abstractMessage" class="anchor"> Abstract Message </a>
-
-A general message as defined by JSON-RPC. The language server protocol always uses "2.0" as the `jsonrpc` version.
-
-<div class="anchorHolder"><a href="#message" name="message" class="linkableAnchor"></a></div>
-
-```typescript
-interface Message {
-	jsonrpc: string;
-}
-```
-#### <a href="#requestMessage" name="requestMessage" class="anchor"> Request Message </a>
-
-A request message to describe a request between the client and the server. Every processed request must send a response back to the sender of the request.
-
-```typescript
-interface RequestMessage extends Message {
-
-	/**
-	 * The request id.
-	 */
-	id: integer | string;
-
-	/**
-	 * The method to be invoked.
-	 */
-	method: string;
-
-	/**
-	 * The method's params.
-	 */
-	params?: array | object;
-}
-```
-
-#### <a href="#responseMessage" name="responseMessage" class="anchor"> Response Message </a>
-
-A Response Message sent as a result of a request. If a request doesn't provide a result value the receiver of a request still needs to return a response message to conform to the JSON-RPC specification. The result property of the ResponseMessage should be set to `null` in this case to signal a successful request.
-
-```typescript
-interface ResponseMessage extends Message {
-	/**
-	 * The request id.
-	 */
-	id: integer | string | null;
-
-	/**
-	 * The result of a request. This member is REQUIRED on success.
-	 * This member MUST NOT exist if there was an error invoking the method.
-	 */
-	result?: string | number | boolean | object | null;
-
-	/**
-	 * The error object in case a request fails.
-	 */
-	error?: ResponseError;
-}
-```
-
-<div class="anchorHolder"><a href="#responseError" name="responseError" class="linkableAnchor"></a></div>
-
-```typescript
-interface ResponseError {
-	/**
-	 * A number indicating the error type that occurred.
-	 */
-	code: integer;
-
-	/**
-	 * A string providing a short description of the error.
-	 */
-	message: string;
-
-	/**
-	 * A primitive or structured value that contains additional
-	 * information about the error. Can be omitted.
-	 */
-	data?: string | number | boolean | array | object | null;
-}
-```
-
-<div class="anchorHolder"><a href="#errorCodes" name="errorCodes" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace ErrorCodes {
-	// Defined by JSON-RPC
-	export const ParseError: integer = -32700;
-	export const InvalidRequest: integer = -32600;
-	export const MethodNotFound: integer = -32601;
-	export const InvalidParams: integer = -32602;
-	export const InternalError: integer = -32603;
-
-	/**
-	 * This is the start range of JSON-RPC reserved error codes.
-	 * It doesn't denote a real error code. No LSP error codes should
-	 * be defined between the start and end range. For backwards
-	 * compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
-	 * are left in the range.
-	 *
-	 * @since 3.16.0
-	 */
-	export const jsonrpcReservedErrorRangeStart: integer = -32099;
-	/** @deprecated use jsonrpcReservedErrorRangeStart */
-	export const serverErrorStart: integer = jsonrpcReservedErrorRangeStart;
-
-	/**
-	 * Error code indicating that a server received a notification or
-	 * request before the server has received the `initialize` request.
-	 */
-	export const ServerNotInitialized: integer = -32002;
-	export const UnknownErrorCode: integer = -32001;
-
-	/**
-	 * This is the end range of JSON-RPC reserved error codes.
-	 * It doesn't denote a real error code.
-	 *
-	 * @since 3.16.0
-	 */
-	export const jsonrpcReservedErrorRangeEnd = -32000;
-	/** @deprecated use jsonrpcReservedErrorRangeEnd */
-	export const serverErrorEnd: integer = jsonrpcReservedErrorRangeEnd;
-
-	/**
-	 * This is the start range of LSP reserved error codes.
-	 * It doesn't denote a real error code.
-	 *
-	 * @since 3.16.0
-	 */
-	export const lspReservedErrorRangeStart: integer = -32899;
-
-	/**
-	 * A request failed but it was syntactically correct, e.g the
-	 * method name was known and the parameters were valid. The error
-	 * message should contain human readable information about why
-	 * the request failed.
-	 *
-	 * @since 3.17.0
-	 */
-	export const RequestFailed: integer = -32803;
-
-	/**
-	 * The server cancelled the request. This error code should
-	 * only be used for requests that explicitly support being
-	 * server cancellable.
-	 *
-	 * @since 3.17.0
-	 */
-	export const ServerCancelled: integer = -32802;
-
-	/**
-	 * The server detected that the content of a document got
-	 * modified outside normal conditions. A server should
-	 * NOT send this error code if it detects a content change
-	 * in it unprocessed messages. The result even computed
-	 * on an older state might still be useful for the client.
-	 *
-	 * If a client decides that a result is not of any use anymore
-	 * the client should cancel the request.
-	 */
-	export const ContentModified: integer = -32801;
-
-	/**
-	 * The client has canceled a request and a server as detected
-	 * the cancel.
-	 */
-	export const RequestCancelled: integer = -32800;
-
-	/**
-	 * This is the end range of LSP reserved error codes.
-	 * It doesn't denote a real error code.
-	 *
-	 * @since 3.16.0
-	 */
-	export const lspReservedErrorRangeEnd: integer = -32800;
-}
-```
-#### <a href="#notificationMessage" name="notificationMessage" class="anchor"> Notification Message </a>
-
-A notification message. A processed notification message must not send a response back. They work like events.
-
-```typescript
-interface NotificationMessage extends Message {
-	/**
-	 * The method to be invoked.
-	 */
-	method: string;
-
-	/**
-	 * The notification's params.
-	 */
-	params?: array | object;
-}
-```
-
-#### <a href="#dollarRequests" name="dollarRequests" class="anchor"> $ Notifications and Requests </a>
-
-Notification and requests whose methods start with '\$/' are messages which are protocol implementation dependent and might not be implementable in all clients or servers. For example if the server implementation uses a single threaded synchronous programming language then there is little a server can do to react to a `$/cancelRequest` notification. If a server or client receives notifications starting with '\$/' it is free to ignore the notification. If a server or client receives a request starting with '\$/' it must error the request with error code `MethodNotFound` (e.g. `-32601`).
-
-#### <a href="#cancelRequest" name="cancelRequest" class="anchor"> Cancellation Support (:arrow_right: :arrow_left:)</a>
-
-The base protocol offers support for request cancellation. To cancel a request, a notification message with the following properties is sent:
-
-_Notification_:
-* method: '$/cancelRequest'
-* params: `CancelParams` defined as follows:
-
-```typescript
-interface CancelParams {
-	/**
-	 * The request id to cancel.
-	 */
-	id: integer | string;
-}
-```
-
-A request that got canceled still needs to return from the server and send a response back. It can not be left open / hanging. This is in line with the JSON-RPC protocol that requires that every request sends a response back. In addition it allows for returning partial results on cancel. If the request returns an error response on cancellation it is advised to set the error code to `ErrorCodes.RequestCancelled`.
-
-#### <a href="#progress" name="progress" class="anchor"> Progress Support (:arrow_right: :arrow_left:)</a>
-
-> *Since version 3.15.0*
-
-The base protocol offers also support to report progress in a generic fashion. This mechanism can be used to report any kind of progress including work done progress (usually used to report progress in the user interface using a progress bar) and partial result progress to support streaming of results.
-
-A progress notification has the following properties:
-
-_Notification_:
-* method: '$/progress'
-* params: `ProgressParams` defined as follows:
-
-```typescript
-type ProgressToken = integer | string;
-```
-
-```typescript
-interface ProgressParams<T> {
-	/**
-	 * The progress token provided by the client or server.
-	 */
-	token: ProgressToken;
-
-	/**
-	 * The progress data.
-	 */
-	value: T;
-}
-```
-
-Progress is reported against a token. The token is different than the request ID which allows to report progress out of band and also for notification.
-
-## <a href="#languageServerProtocol" name="languageServerProtocol" class="anchor"> Language Server Protocol </a>
-
-The language server protocol defines a set of JSON-RPC request, response and notification messages which are exchanged using the above base protocol. This section starts describing the basic JSON structures used in the protocol. The document uses TypeScript interfaces in strict mode to describe these. This means for example that a `null` value has to be explicitly listed and that a mandatory property must be listed even if a falsify value might exist. Based on the basic JSON structures, the actual requests with their responses and the notifications are described.
-
-An example would be a request send from the client to the server to request a hover value for a symbol at a certain position in a text document. The request's method would be `textDocument/hover` with a parameter like this:
-
-```typescript
-interface HoverParams {
-	textDocument: string; /** The text document's URI in string form */
-	position: { line: uinteger; character: uinteger; };
-}
-```
-
-The result of the request would be the hover to be presented. In its simple form it can be a string. So the result looks like this:
-
-```typescript
-interface HoverResult {
-	value: string;
-}
-```
-
-Please also note that a response return value of `null` indicates no result. It doesn't tell the client to resend the request.
-
-In general, the language server protocol supports JSON-RPC messages, however the base protocol defined here uses a convention such that the parameters passed to request/notification messages should be of `object` type (if passed at all). However, this does not disallow using `Array` parameter types in custom messages.
-
-The protocol currently assumes that one server serves one tool. There is currently no support in the protocol to share one server between different tools. Such a sharing would require additional protocol e.g. to lock a document to support concurrent editing.
-
-### <a href="#capabilities" name= "capabilities" class="anchor"> Capabilities </a>
-
-Not every language server can support all features defined by the protocol. LSP therefore provides ‘capabilities’. A capability groups a set of language features. A development tool and the language server announce their supported features using capabilities. As an example, a server announces that it can handle the `textDocument/hover` request, but it might not handle the `workspace/symbol` request. Similarly, a development tool announces its ability to provide `about to save` notifications before a document is saved, so that a server can compute textual edits to format the edited document before it is saved.
-
-The set of capabilities is exchanged between the client and server during the [initialize](#initialize) request.
-
-### <a href="#messageOrdering" name= "messageOrdering" class="anchor"> Request, Notification and Response Ordering </a>
-
-Responses to requests should be sent in roughly the same order as the requests appear on the server or client side. So for example if a server receives a `textDocument/completion` request and then a `textDocument/signatureHelp` request it will usually first return the response for the `textDocument/completion` and then the response for `textDocument/signatureHelp`.
-
-However, the server may decide to use a parallel execution strategy and may wish to return responses in a different order than the requests were received. The server may do so as long as this reordering doesn't affect the correctness of the responses. For example, reordering the result of `textDocument/completion` and `textDocument/signatureHelp` is allowed, as these each of these requests usually won't affect the output of the other. On the other hand, the server most likely should not reorder `textDocument/definition` and `textDocument/rename` requests, since the executing the latter may affect the result of the former.
-
-### <a href="#messageDocumentation" name= "messageDocumentation" class="anchor"> Message Documentation </a>
-
-As said LSP defines a set of requests, responses and notifications. Each of those are document using the following format:
-
-* a header describing the request
-* an optional _Client capability_ section describing the client capability of the request. This includes the client capabilities property path and JSON structure.
-* an optional _Server Capability_ section describing the server capability of the request. This includes the server capabilities property path and JSON structure. Clients should ignore server capabilities they don't understand (e.g. the initialize request shouldn't fail in this case).
-* an optional _Registration Options_ section describing the registration option if the request or notification supports dynamic capability registration. See the [register](#client_registerCapability) and [unregister](#client_unregisterCapability) request for how this works in detail.
-* a _Request_ section describing the format of the request sent. The method is a string identifying the request the params are documented using a TypeScript interface. It is also documented whether the request supports work done progress and partial result progress.
-* a _Response_ section describing the format of the response. The result item describes the returned data in case of a success. The optional partial result item describes the returned data of a partial result notification. The error.data describes the returned data in case of an error. Please remember that in case of a failure the response already contains an error.code and an error.message field. These fields are only specified if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren't listed here.
-
-
-### <a href="#basicJsonStructures" name="basicJsonStructures" class="anchor"> Basic JSON Structures </a>
-
-There are quite some JSON structures that are shared between different requests and notifications. Their structure and capabilities are document in this section.
-
-#### <a href="#uri" name="uri" class="anchor"> URI </a>
-
-URI's are transferred as strings. The URI's format is defined in [https://tools.ietf.org/html/rfc3986](https://tools.ietf.org/html/rfc3986)
-
-```
-  foo://example.com:8042/over/there?name=ferret#nose
-  \_/   \______________/\_________/ \_________/ \__/
-   |           |            |            |        |
-scheme     authority       path        query   fragment
-   |   _____________________|__
-  / \ /                        \
-  urn:example:animal:ferret:nose
-```
-
-We also maintain a node module to parse a string into `scheme`, `authority`, `path`, `query`, and `fragment` URI components. The GitHub repository is [https://github.com/Microsoft/vscode-uri](https://github.com/Microsoft/vscode-uri) the npm module is [https://www.npmjs.com/package/vscode-uri](https://www.npmjs.com/package/vscode-uri).
-
-Many of the interfaces contain fields that correspond to the URI of a document. For clarity, the type of such a field is declared as a `DocumentUri`. Over the wire, it will still be transferred as a string, but this guarantees that the contents of that string can be parsed as a valid URI.
-
-<div class="anchorHolder"><a href="#documentUri" name="documentUri" class="linkableAnchor"></a></div>
-
-```typescript
-type DocumentUri = string;
-```
-
-There is also a tagging interface for normal non document URIs. It maps to a `string` as well.
-
-```typescript
-type URI = string;
-```
-#### <a href="#regExp" name="regExp" class="anchor"> Regular Expressions </a>
-
-Regular expression are a powerful tool and there are actual use cases for them in the language server protocol. However the downside with them is that almost every programming language has its own set of regular expression features so the specification can not simply refer to them as a regular expression. So the LSP uses a two step approach to support regular expressions:
-
-* the client will announce which regular expression engine it will use. This will allow server that are written for a very specific client make full use of the regular expression capabilities of the client
-* the specification will define a set of regular expression features that should be supported by a client. Instead of writing a new specification LSP will refer to the [ECMAScript Regular Expression specification](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) and remove features from it that are not necessary in the context of LSP or hard to implement for other clients.
-
-_Client Capability_:
-
-The following client capability is used to announce a client's regular expression engine
-
-* property path (optional): `general.regularExpressions`
-* property type: `RegularExpressionsClientCapabilities` defined as follows:
-
-```typescript
-/**
- * Client capabilities specific to regular expressions.
- */
-export interface RegularExpressionsClientCapabilities {
-	/**
-	 * The engine's name.
-	 */
-	engine: string;
-
-	/**
-	 * The engine's version.
-	 */
-	version?: string;
-}
-```
-
-The following table lists the well known engine values. Please note that the table should be driven by the community which integrates LSP into existing clients. It is not the goal of the spec to list all available regular expression engines.
-
-Engine | Version | Documentation
-------- | ------- | -------------
-ECMAScript | `ES2020` | [ECMAScript 2020](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) & [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
-
-_Regular Expression Subset_:
-
-The following features from the [ECMAScript 2020](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) regular expression specification are NOT mandatory for a client:
-
-- *Assertions*: Lookahead assertion, Negative lookahead assertion, lookbehind assertion, negative lookbehind assertion.
-- *Character classes*: matching control characters using caret notation (e.g. `\cX`) and matching UTF-16 code units (e.g. `\uhhhh`).
-- *Group and ranges*: named capturing groups.
-- *Unicode property escapes*: none of the features needs to be supported.
-
-The only regular expression flag that a client needs to support is 'i' to specify a case insensitive search.
-
-#### <a href="#enumerations" name="enumerations" class="anchor"> Enumerations </a>
-
-The protocol supports two kind of enumerations: (a) integer based enumerations and (b) strings based enumerations. Integer based enumerations usually start with `1`. The onces that don't are historical and they were kept to stay backwards compatible. If appropriate the value set of an enumeration is announced by the defining side (e.g. client or server) and transmitted to the other side during the initialize handshake. An example is the `CompletionItemKind` enumeration. It is announced by the client using the `textDocument.completion.completionItemKind` client property.
-
-To support the evolution of enumerations the using side of an enumeration shouldn't fail on an enumeration value it doesn't know. It should simply ignore it as a value it can use and try to do its best to preserve the value on round trips. Lets look at the `CompletionItemKind` enumeration as an example again: if in a future version of the specification an additional completion item kind with the value `n` gets added and announced by a client a (older) server not knowing about the value should not fail but simply ignore the value as a usable item kind.
-
-
-#### <a href="#textDocuments" name="textDocuments" class="anchor"> Text Documents </a>
-
-The current protocol is tailored for textual documents whose content can be represented as a string. There is currently no support for binary documents. A position inside a document (see Position definition below) is expressed as a zero-based line and character offset.
-
-> New in 3.17
-
-Prior to 3.17 the offsets were always based on a UTF-16 string representation. So a string of the form `a𐐀b` the character offset of the character `a` is 0, the character offset of `𐐀` is 1 and the character offset of b is 3 since `𐐀` is represented using two code units in UTF-16. Since 3.17 clients and servers can agree on a different string encoding representation (e.g. UTF-8). The client announces it's supported encoding via the client capability [`general.positionEncodings`](#clientCapabilities). The value is an array of position encodings the client supports, with decreasing preference (e.g. the encoding at index `0` is the most preferred one). To stay backwards compatible the only mandatory encoding is UTF-16 represented via the string `utf-16`. The server can pick one of the encodings offered by the client and signals that encoding back to the client via the initialize result's property [`capabilities.positionEncoding`](#serverCapabilities). If the string value `utf-16` is missing from the client's capability `general.positionEncodings` servers can safely assume that the client supports UTF-16. If the server omits the position encoding in its initialize result the encoding defaults to the string value `utf-16`. Implementation considerations: since the conversion from one encoding into another requires the content of the file / line the conversion is best done where the file is read which is usually on the server side.
-
-To ensure that both client and server split the string into the same line representation the protocol specifies the following end-of-line sequences: '\n', '\r\n' and '\r'. Positions are line end character agnostic. So you can not specify a position that denotes `\r|\n` or `\n|` where `|` represents the character offset.
-
-```typescript
-export const EOL: string[] = ['\n', '\r\n', '\r'];
-```
-
-#### <a href="#position" name="position" class="anchor"> Position </a>
-
-Position in a text document expressed as zero-based line and zero-based character offset. A position is between two characters like an 'insert' cursor in an editor. Special values like for example `-1` to denote the end of a line are not supported.
-
-```typescript
-interface Position {
-	/**
-	 * Line position in a document (zero-based).
-	 */
-	line: uinteger;
-
-	/**
-	 * Character offset on a line in a document (zero-based). The meaning of this
-	 * offset is determined by the negotiated `PositionEncodingKind`.
-	 *
-	 * If the character value is greater than the line length it defaults back
-	 * to the line length.
-	 */
-	character: uinteger;
-}
-```
-
-When describing positions the protocol needs to specify how offsets (specifically character offsets) should be interpreted.
-The corresponding `PositionEncodingKind` is negotiated between the client and the server during initialization.
-
-<div class="anchorHolder"><a href="#positionEncodingKind" name="positionEncodingKind" class="linkableAnchor"></a></div>
-
-
-```typescript
-/**
- * A type indicating how positions are encoded,
- * specifically what column offsets mean.
- *
- * @since 3.17.0
- */
-export type PositionEncodingKind = string;
-
-/**
- * A set of predefined position encoding kinds.
- *
- * @since 3.17.0
- */
-export namespace PositionEncodingKind {
-
-	/**
-	 * Character offsets count UTF-8 code units.
-	 */
-	export const UTF8: PositionEncodingKind = 'utf-8';
-
-	/**
-	 * Character offsets count UTF-16 code units.
-	 *
-	 * This is the default and must always be supported
-	 * by servers
-	 */
-	export const UTF16: PositionEncodingKind = 'utf-16';
-
-	/**
-	 * Character offsets count UTF-32 code units.
-	 *
-	 * Implementation note: these are the same as Unicode code points,
-	 * so this `PositionEncodingKind` may also be used for an
-	 * encoding-agnostic representation of character offsets.
-	 */
-	export const UTF32: PositionEncodingKind = 'utf-32';
-}
-```
-
-#### <a href="#range" name="range" class="anchor"> Range </a>
-
-A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor. Therefore the end position is exclusive. If you want to specify a range that contains a line including the line ending character(s) then use an end position denoting the start of the next line. For example:
-```typescript
-{
-    start: { line: 5, character: 23 },
-    end : { line: 6, character: 0 }
-}
-```
-
-```typescript
-interface Range {
-	/**
-	 * The range's start position.
-	 */
-	start: Position;
-
-	/**
-	 * The range's end position.
-	 */
-	end: Position;
-}
-```
-
-#### <a href="#textDocumentItem" name="textDocumentItem" class="anchor"> TextDocumentItem </a>
-
-An item to transfer a text document from the client to the server.
-
-```typescript
-interface TextDocumentItem {
-	/**
-	 * The text document's URI.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The text document's language identifier.
-	 */
-	languageId: string;
-
-	/**
-	 * The version number of this document (it will increase after each
-	 * change, including undo/redo).
-	 */
-	version: integer;
-
-	/**
-	 * The content of the opened text document.
-	 */
-	text: string;
-}
-```
-
-Text documents have a language identifier to identify a document on the server side when it handles more than one language to avoid re-interpreting the file extension. If a document refers to one of the programming languages listed below it is recommended that clients use those ids.
-
-Language | Identifier
--------- | ----------
-ABAP | `abap`
-Windows Bat | `bat`
-BibTeX | `bibtex`
-Clojure | `clojure`
-Coffeescript | `coffeescript`
-C | `c`
-C++ | `cpp`
-C# | `csharp`
-CSS | `css`
-Diff | `diff`
-Dart | `dart`
-Dockerfile | `dockerfile`
-Elixir | `elixir`
-Erlang | `erlang`
-F# | `fsharp`
-Git | `git-commit` and `git-rebase`
-Go | `go`
-Groovy | `groovy`
-Handlebars | `handlebars`
-HTML | `html`
-Ini | `ini`
-Java | `java`
-JavaScript | `javascript`
-JavaScript React | `javascriptreact`
-JSON | `json`
-LaTeX | `latex`
-Less | `less`
-Lua | `lua`
-Makefile | `makefile`
-Markdown | `markdown`
-Objective-C | `objective-c`
-Objective-C++ | `objective-cpp`
-Perl | `perl`
-Perl 6 | `perl6`
-PHP | `php`
-Powershell | `powershell`
-Pug | `jade`
-Python | `python`
-R | `r`
-Razor (cshtml) | `razor`
-Ruby | `ruby`
-Rust | `rust`
-SCSS | `scss` (syntax using curly brackets), `sass` (indented syntax)
-Scala | `scala`
-ShaderLab | `shaderlab`
-Shell Script (Bash) | `shellscript`
-SQL | `sql`
-Swift | `swift`
-TypeScript | `typescript`
-TypeScript React| `typescriptreact`
-TeX | `tex`
-Visual Basic | `vb`
-XML | `xml`
-XSL | `xsl`
-YAML | `yaml`
-{: .table .table-bordered .table-responsive}
-
-
-#### <a href="#textDocumentIdentifier" name="textDocumentIdentifier" class="anchor"> TextDocumentIdentifier </a>
-
-Text documents are identified using a URI. On the protocol level, URIs are passed as strings. The corresponding JSON structure looks like this:
-```typescript
-interface TextDocumentIdentifier {
-	/**
-	 * The text document's URI.
-	 */
-	uri: DocumentUri;
-}
-```
-#### <a href="#versionedTextDocumentIdentifier" name="versionedTextDocumentIdentifier" class="anchor"> VersionedTextDocumentIdentifier </a>
-
-An identifier to denote a specific version of a text document. This information usually flows from the client to the server.
-
-```typescript
-interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
-	/**
-	 * The version number of this document.
-	 *
-	 * The version number of a document will increase after each change,
-	 * including undo/redo. The number doesn't need to be consecutive.
-	 */
-	version: integer;
-}
-```
-
-An identifier which optionally denotes a specific version of a text document. This information usually flows from the server to the client.
-
-<div class="anchorHolder"><a href="#optionalVersionedTextDocumentIdentifier" name="optionalVersionedTextDocumentIdentifier" class="linkableAnchor"></a></div>
-
-```typescript
-interface OptionalVersionedTextDocumentIdentifier extends TextDocumentIdentifier {
-	/**
-	 * The version number of this document. If an optional versioned text document
-	 * identifier is sent from the server to the client and the file is not
-	 * open in the editor (the server has not received an open notification
-	 * before) the server can send `null` to indicate that the version is
-	 * known and the content on disk is the master (as specified with document
-	 * content ownership).
-	 *
-	 * The version number of a document will increase after each change,
-	 * including undo/redo. The number doesn't need to be consecutive.
-	 */
-	version: integer | null;
-}
-```
-#### <a href="#textDocumentPositionParams" name="textDocumentPositionParams" class="anchor"> TextDocumentPositionParams </a>
-
-Was `TextDocumentPosition` in 1.0 with inlined parameters.
-
-A parameter literal used in requests to pass a text document and a position inside that document. It is up to the client to decide how a selection is converted into a position when issuing a request for a text document. The client can for example honor or ignore the selection direction to make LSP request consistent with features implemented internally.
-
-```typescript
-interface TextDocumentPositionParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The position inside the text document.
-	 */
-	position: Position;
-}
-```
-#### <a href="#documentFilter" name="documentFilter" class="anchor"> DocumentFilter </a>
-
-A document filter denotes a document through properties like `language`, `scheme` or `pattern`. An example is a filter that applies to TypeScript files on disk. Another example is a filter the applies to JSON files with name `package.json`:
-```typescript
-{ language: 'typescript', scheme: 'file' }
-{ language: 'json', pattern: '**/package.json' }
-```
-
-```typescript
-export interface DocumentFilter {
-	/**
-	 * A language id, like `typescript`.
-	 */
-	language?: string;
-
-	/**
-	 * A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
-	 */
-	scheme?: string;
-
-	/**
-	 * A glob pattern, like `*.{ts,js}`.
-	 *
-	 * 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`)
-	 */
-	pattern?: string;
-}
-```
-
-A document selector is the combination of one or more document filters.
-
-<div class="anchorHolder"><a href="#documentSelector" name="documentSelector" class="linkableAnchor"></a></div>
-
-```typescript
-export type DocumentSelector = DocumentFilter[];
-```
-
-#### <a href="#textEdit" name="textEdit" class="anchor"> TextEdit & AnnotatedTextEdit </a>
-
-> New in version 3.16: Support for `AnnotatedTextEdit`.
-
-A textual edit applicable to a text document.
-
-```typescript
-interface TextEdit {
-	/**
-	 * The range of the text document to be manipulated. To insert
-	 * text into a document create a range where start === end.
-	 */
-	range: Range;
-
-	/**
-	 * The string to be inserted. For delete operations use an
-	 * empty string.
-	 */
-	newText: string;
-}
-```
-Since 3.16.0 there is also the concept of an annotated text edit which supports to add an annotation to a text edit. The annotation can add information describing the change to the text edit.
-
-<div class="anchorHolder"><a href="#changeAnnotation" name="changeAnnotation" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Additional information that describes document changes.
- *
- * @since 3.16.0
- */
-export interface ChangeAnnotation {
-	/**
-	 * A human-readable string describing the actual change. The string
-	 * is rendered prominent in the user interface.
-	 */
-	label: string;
-
-	/**
-	 * A flag which indicates that user confirmation is needed
-	 * before applying the change.
-	 */
-	needsConfirmation?: boolean;
-
-	/**
-	 * A human-readable string which is rendered less prominent in
-	 * the user interface.
-	 */
-	description?: string;
-}
-```
-
-Usually clients provide options to group the changes along the annotations they are associated with. To support this in the protocol an edit or resource operation refers to a change annotation using an identifier and not the change annotation literal directly. This allows servers to use the identical annotation across multiple edits or resource operations which then allows clients to group the operations under that change annotation. The actual change annotations together with their identifiers are managed by the workspace edit via the new property `changeAnnotations`.
-
-<div class="anchorHolder"><a href="#changeAnnotationIdentifier" name="changeAnnotationIdentifier" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * An identifier referring to a change annotation managed by a workspace
- * edit.
- *
- * @since 3.16.0.
- */
-export type ChangeAnnotationIdentifier = string;
-```
-
-<div class="anchorHolder"><a href="#annotatedTextEdit" name="annotatedTextEdit" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A special text edit with an additional change annotation.
- *
- * @since 3.16.0.
- */
-export interface AnnotatedTextEdit extends TextEdit {
-	/**
-	 * The actual annotation identifier.
-	 */
-	annotationId: ChangeAnnotationIdentifier;
-}
-```
-#### <a href="#textEditArray" name="textEditArray" class="anchor"> TextEdit[] </a>
-
-Complex text manipulations are described with an array of `TextEdit`'s or `AnnotatedTextEdit`'s, representing a single change to the document.
-
-All text edits ranges refer to positions in the document the are computed on. They therefore move a document from state S1 to S2 without describing any intermediate state. Text edits ranges must never overlap, that means no part of the original document must be manipulated by more than one edit. However, it is possible that multiple edits have the same start position: multiple inserts, or any number of inserts followed by a single remove or replace edit. If multiple inserts have the same position, the order in the array defines the order in which the inserted strings appear in the resulting text.
-
-#### <a href="#textDocumentEdit" name="textDocumentEdit" class="anchor"> TextDocumentEdit </a>
-
-> New in version 3.16: support for `AnnotatedTextEdit`. The support is guarded by the client capability `workspace.workspaceEdit.changeAnnotationSupport`. If a client doesn't signal the capability, servers shouldn't send `AnnotatedTextEdit` literals back to the client.
-
-Describes textual changes on a single text document. The text document is referred to as a `OptionalVersionedTextDocumentIdentifier` to allow clients to check the text document version before an edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to sort the array of edits or do any kind of ordering. However the edits must be non overlapping.
-
-```typescript
-export interface TextDocumentEdit {
-	/**
-	 * The text document to change.
-	 */
-	textDocument: OptionalVersionedTextDocumentIdentifier;
-
-	/**
-	 * The edits to be applied.
-	 *
-	 * @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the
-	 * client capability `workspace.workspaceEdit.changeAnnotationSupport`
-	 */
-	edits: (TextEdit | AnnotatedTextEdit)[];
-}
-```
-#### <a href="#location" name="location" class="anchor"> Location </a>
-
-Represents a location inside a resource, such as a line inside a text file.
-```typescript
-interface Location {
-	uri: DocumentUri;
-	range: Range;
-}
-```
-#### <a href="#locationLink" name="locationLink" class="anchor"> LocationLink </a>
-
-Represents a link between a source and a target location.
-
-```typescript
-interface LocationLink {
-
-	/**
-	 * Span of the origin of this link.
-	 *
-	 * Used as the underlined span for mouse interaction. Defaults to the word
-	 * range at the mouse position.
-	 */
-	originSelectionRange?: Range;
-
-	/**
-	 * The target resource identifier of this link.
-	 */
-	targetUri: DocumentUri;
-
-	/**
-	 * The full target range of this link. If the target for example is a symbol
-	 * then target range is the range enclosing this symbol not including
-	 * leading/trailing whitespace but everything else like comments. This
-	 * information is typically used to highlight the range in the editor.
-	 */
-	targetRange: Range;
-
-	/**
-	 * The range that should be selected and revealed when this link is being
-	 * followed, e.g the name of a function. Must be contained by the the
-	 * `targetRange`. See also `DocumentSymbol#range`
-	 */
-	targetSelectionRange: Range;
-}
-```
-#### <a href="#diagnostic" name="diagnostic" class="anchor"> Diagnostic </a>
-
-Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the scope of a resource.
-
-```typescript
-export interface Diagnostic {
-	/**
-	 * The range at which the message applies.
-	 */
-	range: Range;
-
-	/**
-	 * The diagnostic's severity. Can be omitted. If omitted it is up to the
-	 * client to interpret diagnostics as error, warning, info or hint.
-	 */
-	severity?: DiagnosticSeverity;
-
-	/**
-	 * The diagnostic's code, which might appear in the user interface.
-	 */
-	code?: integer | string;
-
-	/**
-	 * An optional property to describe the error code.
-	 *
-	 * @since 3.16.0
-	 */
-	codeDescription?: CodeDescription;
-
-	/**
-	 * A human-readable string describing the source of this
-	 * diagnostic, e.g. 'typescript' or 'super lint'.
-	 */
-	source?: string;
-
-	/**
-	 * The diagnostic's message.
-	 */
-	message: string;
-
-	/**
-	 * Additional metadata about the diagnostic.
-	 *
-	 * @since 3.15.0
-	 */
-	tags?: DiagnosticTag[];
-
-	/**
-	 * An array of related diagnostic information, e.g. when symbol-names within
-	 * a scope collide all definitions can be marked via this property.
-	 */
-	relatedInformation?: DiagnosticRelatedInformation[];
-
-	/**
-	 * A data entry field that is preserved between a
-	 * `textDocument/publishDiagnostics` notification and
-	 * `textDocument/codeAction` request.
-	 *
-	 * @since 3.16.0
-	 */
-	data?: unknown;
-}
-```
-
-The protocol currently supports the following diagnostic severities and tags:
-
-<div class="anchorHolder"><a href="#diagnosticSeverity" name="diagnosticSeverity" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace DiagnosticSeverity {
-	/**
-	 * Reports an error.
-	 */
-	export const Error: 1 = 1;
-	/**
-	 * Reports a warning.
-	 */
-	export const Warning: 2 = 2;
-	/**
-	 * Reports an information.
-	 */
-	export const Information: 3 = 3;
-	/**
-	 * Reports a hint.
-	 */
-	export const Hint: 4 = 4;
-}
-
-export type DiagnosticSeverity = 1 | 2 | 3 | 4;
-```
-
-<div class="anchorHolder"><a href="#diagnosticTag" name="diagnosticTag" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The diagnostic tags.
- *
- * @since 3.15.0
- */
-export namespace DiagnosticTag {
-	/**
-	 * Unused or unnecessary code.
-	 *
-	 * Clients are allowed to render diagnostics with this tag faded out
-	 * instead of having an error squiggle.
-	 */
-	export const Unnecessary: 1 = 1;
-	/**
-	 * Deprecated or obsolete code.
-	 *
-	 * Clients are allowed to rendered diagnostics with this tag strike through.
-	 */
-	export const Deprecated: 2 = 2;
-}
-
-export type DiagnosticTag = 1 | 2;
-```
-
-`DiagnosticRelatedInformation` is defined as follows:
-
-<div class="anchorHolder"><a href="#diagnosticRelatedInformation" name="diagnosticRelatedInformation" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents a related message and source code location for a diagnostic.
- * This should be used to point to code locations that cause or are related to
- * a diagnostics, e.g when duplicating a symbol in a scope.
- */
-export interface DiagnosticRelatedInformation {
-	/**
-	 * The location of this related diagnostic information.
-	 */
-	location: Location;
-
-	/**
-	 * The message of this related diagnostic information.
-	 */
-	message: string;
-}
-```
-
-`CodeDescription` is defined as follows:
-
-<div class="anchorHolder"><a href="#codeDescription" name="codeDescription" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Structure to capture a description for an error code.
- *
- * @since 3.16.0
- */
-export interface CodeDescription {
-	/**
-	 * An URI to open with more information about the diagnostic error.
-	 */
-	href: URI;
-}
-```
-#### <a href="#command" name="command" class="anchor"> Command </a>
-
-Represents a reference to a command. Provides a title which will be used to represent a command in the UI. Commands are identified by a string identifier. The recommended way to handle commands is to implement their execution on the server side if the client and server provides the corresponding capabilities. Alternatively the tool extension code could handle the command. The protocol currently doesn't specify a set of well-known commands.
-
-```typescript
-interface Command {
-	/**
-	 * Title of the command, like `save`.
-	 */
-	title: string;
-	/**
-	 * The identifier of the actual command handler.
-	 */
-	command: string;
-	/**
-	 * Arguments that the command handler should be
-	 * invoked with.
-	 */
-	arguments?: LSPAny[];
-}
-```
-#### <a href="#markupContent" name="markupContent" class="anchor"> MarkupContent </a>
-
- A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`. If the format is `markdown` the content should follow the [GitHub Flavored Markdown Specification](https://github.github.com/gfm/).
-
-```typescript
-/**
- * Describes the content type that a client supports in various
- * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
- *
- * Please note that `MarkupKinds` must not start with a `$`. This kinds
- * are reserved for internal usage.
- */
-export namespace MarkupKind {
-	/**
-	 * Plain text is supported as a content format
-	 */
-	export const PlainText: 'plaintext' = 'plaintext';
-
-	/**
-	 * Markdown is supported as a content format
-	 */
-	export const Markdown: 'markdown' = 'markdown';
-}
-export type MarkupKind = 'plaintext' | 'markdown';
-```
-
-<div class="anchorHolder"><a href="#markupContentDefinition" name="markupContentInnerDefinition" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A `MarkupContent` literal represents a string value which content is
- * interpreted base on its kind flag. Currently the protocol supports
- * `plaintext` and `markdown` as markup kinds.
- *
- * If the kind is `markdown` then the value can contain fenced code blocks like
- * in GitHub issues.
- *
- * Here is an example how such a string can be constructed using
- * JavaScript / TypeScript:
- * ```typescript
- * let markdown: MarkdownContent = {
- * 	kind: MarkupKind.Markdown,
- * 	value: [
- * 		'# Header',
- * 		'Some text',
- * 		'```typescript',
- * 		'someCode();',
- * 		'```'
- * 	].join('\n')
- * };
- * ```
- *
- * *Please Note* that clients might sanitize the return markdown. A client could
- * decide to remove HTML from the markdown to avoid script execution.
- */
-export interface MarkupContent {
-	/**
-	 * The type of the Markup
-	 */
-	kind: MarkupKind;
-
-	/**
-	 * The content itself
-	 */
-	value: string;
-}
-```
-
-In addition clients should signal the markdown parser they are using via the client capability `general.markdown` introduced in version 3.16.0 defined as follows:
-
-<div class="anchorHolder"><a href="#markdownClientCapabilities" name="markdownClientCapabilities" class="linkableAnchor"></a></div>
-
- ```typescript
-/**
- * Client capabilities specific to the used markdown parser.
- *
- * @since 3.16.0
- */
-export interface MarkdownClientCapabilities {
-	/**
-	 * The name of the parser.
-	 */
-	parser: string;
-
-	/**
-	 * The version of the parser.
-	 */
-	version?: string;
-
-	/**
-	 * A list of HTML tags that the client allows / supports in
-	 * Markdown.
-	 *
-	 * @since 3.17.0
-	 */
-	allowedTags?: string[];
-}
- ```
-
-Known markdown parsers used by clients right now are:
-
-Parser          | Version | Documentation
---------------- | ------- | -------------
-marked          | 1.1.0   | [Marked Documentation](https://marked.js.org/)
-Python-Markdown | 3.2.2   | [Python-Markdown Documentation](https://python-markdown.github.io)
-### <a href="#resourceChanges" name="resourceChanges" class="anchor"> File Resource changes </a>
-
-> New in version 3.13. Since version 3.16 file resource changes can carry an additional property `changeAnnotation` to describe the actual change in more detail. Whether a client has support for change annotations is guarded by the client capability `workspace.workspaceEdit.changeAnnotationSupport`.
-
-File resource changes allow servers to create, rename and delete files and folders via the client. Note that the names talk about files but the operations are supposed to work on files and folders. This is in line with other naming in the Language Server Protocol (see file watchers which can watch files and folders). The corresponding change literals look as follows:
-
-<div class="anchorHolder"><a href="#createFileOptions" name="createFileOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Options to create a file.
- */
-export interface CreateFileOptions {
-	/**
-	 * Overwrite existing file. Overwrite wins over `ignoreIfExists`
-	 */
-	overwrite?: boolean;
-
-	/**
-	 * Ignore if exists.
-	 */
-	ignoreIfExists?: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#createFile" name="createFile" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Create file operation
- */
-export interface CreateFile {
-	/**
-	 * A create
-	 */
-	kind: 'create';
-
-	/**
-	 * The resource to create.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * Additional options
-	 */
-	options?: CreateFileOptions;
-
-	/**
-	 * An optional annotation identifier describing the operation.
-	 *
-	 * @since 3.16.0
-	 */
-	annotationId?: ChangeAnnotationIdentifier;
-}
-```
-
-<div class="anchorHolder"><a href="#renameFileOptions" name="renameFileOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Rename file options
- */
-export interface RenameFileOptions {
-	/**
-	 * Overwrite target if existing. Overwrite wins over `ignoreIfExists`
-	 */
-	overwrite?: boolean;
-
-	/**
-	 * Ignores if target exists.
-	 */
-	ignoreIfExists?: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#renameFile" name="renameFile" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Rename file operation
- */
-export interface RenameFile {
-	/**
-	 * A rename
-	 */
-	kind: 'rename';
-
-	/**
-	 * The old (existing) location.
-	 */
-	oldUri: DocumentUri;
-
-	/**
-	 * The new location.
-	 */
-	newUri: DocumentUri;
-
-	/**
-	 * Rename options.
-	 */
-	options?: RenameFileOptions;
-
-	/**
-	 * An optional annotation identifier describing the operation.
-	 *
-	 * @since 3.16.0
-	 */
-	annotationId?: ChangeAnnotationIdentifier;
-}
-```
-
-<div class="anchorHolder"><a href="#deleteFileOptions" name="deleteFileOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Delete file options
- */
-export interface DeleteFileOptions {
-	/**
-	 * Delete the content recursively if a folder is denoted.
-	 */
-	recursive?: boolean;
-
-	/**
-	 * Ignore the operation if the file doesn't exist.
-	 */
-	ignoreIfNotExists?: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#deleteFile" name="deleteFile" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Delete file operation
- */
-export interface DeleteFile {
-	/**
-	 * A delete
-	 */
-	kind: 'delete';
-
-	/**
-	 * The file to delete.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * Delete options.
-	 */
-	options?: DeleteFileOptions;
-
-	/**
-	 * An optional annotation identifier describing the operation.
-	 *
-	 * @since 3.16.0
-	 */
-	annotationId?: ChangeAnnotationIdentifier;
-}
-```
-#### <a href="#workspaceEdit" name="workspaceEdit" class="anchor"> WorkspaceEdit </a>
-
-A workspace edit represents changes to many resources managed in the workspace. The edit should either provide `changes` or `documentChanges`. If the client can handle versioned document edits and if `documentChanges` are present, the latter are preferred over `changes`.
-
- Since version 3.13.0 a workspace edit can contain resource operations (create, delete or rename files and folders) as well. If resource operations are present clients need to execute the operations in the order in which they are provided. So a workspace edit for example can consist of the following two changes: (1) create file a.txt and (2) a text document edit which insert text into file a.txt. An invalid sequence (e.g. (1) delete file a.txt and (2) insert text into file a.txt) will cause failure of the operation. How the client recovers from the failure is described by the client capability: `workspace.workspaceEdit.failureHandling`
-
-```typescript
-export interface WorkspaceEdit {
-	/**
-	 * Holds changes to existing resources.
-	 */
-	changes?: { [uri: DocumentUri]: TextEdit[]; };
-
-	/**
-	 * Depending on the client capability
-	 * `workspace.workspaceEdit.resourceOperations` document changes are either
-	 * an array of `TextDocumentEdit`s to express changes to n different text
-	 * documents where each text document edit addresses a specific version of
-	 * a text document. Or it can contain above `TextDocumentEdit`s mixed with
-	 * create, rename and delete file / folder operations.
-	 *
-	 * Whether a client supports versioned document edits is expressed via
-	 * `workspace.workspaceEdit.documentChanges` client capability.
-	 *
-	 * If a client neither supports `documentChanges` nor
-	 * `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
-	 * using the `changes` property are supported.
-	 */
-	documentChanges?: (
-		TextDocumentEdit[] |
-		(TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]
-	);
-
-	/**
-	 * A map of change annotations that can be referenced in
-	 * `AnnotatedTextEdit`s or create, rename and delete file / folder
-	 * operations.
-	 *
-	 * Whether clients honor this property depends on the client capability
-	 * `workspace.changeAnnotationSupport`.
-	 *
-	 * @since 3.16.0
-	 */
-	changeAnnotations?: {
-		[id: string /* ChangeAnnotationIdentifier */]: ChangeAnnotation;
-	};
-}
-```
-
-##### <a href="#workspaceEditClientCapabilities" name="workspaceEditClientCapabilities" class="anchor"> WorkspaceEditClientCapabilities </a>
-
-> New in version 3.13: `ResourceOperationKind` and `FailureHandlingKind` and the client capability `workspace.workspaceEdit.resourceOperations` as well as `workspace.workspaceEdit.failureHandling`.
-
-
-The capabilities of a workspace edit has evolved over the time. Clients can describe their support using the following client capability:
-
-_Client Capability_:
-* property path (optional): `workspace.workspaceEdit`
-* property type: `WorkspaceEditClientCapabilities` defined as follows:
-
-```typescript
-export interface WorkspaceEditClientCapabilities {
-	/**
-	 * The client supports versioned document changes in `WorkspaceEdit`s
-	 */
-	documentChanges?: boolean;
-
-	/**
-	 * The resource operations the client supports. Clients should at least
-	 * support 'create', 'rename' and 'delete' files and folders.
-	 *
-	 * @since 3.13.0
-	 */
-	resourceOperations?: ResourceOperationKind[];
-
-	/**
-	 * The failure handling strategy of a client if applying the workspace edit
-	 * fails.
-	 *
-	 * @since 3.13.0
-	 */
-	failureHandling?: FailureHandlingKind;
-
-	/**
-	 * Whether the client normalizes line endings to the client specific
-	 * setting.
-	 * If set to `true` the client will normalize line ending characters
-	 * in a workspace edit to the client specific new line character(s).
-	 *
-	 * @since 3.16.0
-	 */
-	normalizesLineEndings?: boolean;
-
-	/**
-	 * Whether the client in general supports change annotations on text edits,
-	 * create file, rename file and delete file changes.
-	 *
-	 * @since 3.16.0
-	 */
-	changeAnnotationSupport?: {
-		/**
-		 * Whether the client groups edits with equal labels into tree nodes,
-		 * for instance all edits labelled with "Changes in Strings" would
-		 * be a tree node.
-		 */
-		groupsOnLabel?: boolean;
-	};
-}
-```
-
-<div class="anchorHolder"><a href="#resourceOperationKind" name="resourceOperationKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The kind of resource operations supported by the client.
- */
-export type ResourceOperationKind = 'create' | 'rename' | 'delete';
-
-export namespace ResourceOperationKind {
-
-	/**
-	 * Supports creating new files and folders.
-	 */
-	export const Create: ResourceOperationKind = 'create';
-
-	/**
-	 * Supports renaming existing files and folders.
-	 */
-	export const Rename: ResourceOperationKind = 'rename';
-
-	/**
-	 * Supports deleting existing files and folders.
-	 */
-	export const Delete: ResourceOperationKind = 'delete';
-}
-```
-
-<div class="anchorHolder"><a href="#failureHandlingKind" name="failureHandlingKind" class="linkableAnchor"></a></div>
-
-```typescript
-export type FailureHandlingKind = 'abort' | 'transactional' | 'undo'
-	| 'textOnlyTransactional';
-
-export namespace FailureHandlingKind {
-
-	/**
-	 * Applying the workspace change is simply aborted if one of the changes
-	 * provided fails. All operations executed before the failing operation
-	 * stay executed.
-	 */
-	export const Abort: FailureHandlingKind = 'abort';
-
-	/**
-	 * All operations are executed transactional. That means they either all
-	 * succeed or no changes at all are applied to the workspace.
-	 */
-	export const Transactional: FailureHandlingKind = 'transactional';
-
-
-	/**
-	 * If the workspace edit contains only textual file changes they are
-	 * executed transactional. If resource changes (create, rename or delete
-	 * file) are part of the change the failure handling strategy is abort.
-	 */
-	export const TextOnlyTransactional: FailureHandlingKind
-		= 'textOnlyTransactional';
-
-	/**
-	 * The client tries to undo the operations already executed. But there is no
-	 * guarantee that this is succeeding.
-	 */
-	export const Undo: FailureHandlingKind = 'undo';
-}
-```
-
-#### <a href="#workDoneProgress" name="workDoneProgress" class="anchor"> Work Done Progress </a>
-
-> *Since version 3.15.0*
-
-Work done progress is reported using the generic [`$/progress`](#progress) notification. The value payload of a work done progress notification can be of three different forms.
-
-##### <a href="#workDoneProgressBegin" name="workDoneProgressBegin" class="anchor"> Work Done Progress Begin </a>
-
-To start progress reporting a `$/progress` notification with the following payload must be sent:
-
-```typescript
-export interface WorkDoneProgressBegin {
-
-	kind: 'begin';
-
-	/**
-	 * Mandatory title of the progress operation. Used to briefly inform about
-	 * the kind of operation being performed.
-	 *
-	 * Examples: "Indexing" or "Linking dependencies".
-	 */
-	title: string;
-
-	/**
-	 * Controls if a cancel button should show to allow the user to cancel the
-	 * long running operation. Clients that don't support cancellation are
-	 * allowed to ignore the setting.
-	 */
-	cancellable?: boolean;
-
-	/**
-	 * Optional, more detailed associated progress message. Contains
-	 * complementary information to the `title`.
-	 *
-	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
-	 * If unset, the previous progress message (if any) is still valid.
-	 */
-	message?: string;
-
-	/**
-	 * Optional progress percentage to display (value 100 is considered 100%).
-	 * If not provided infinite progress is assumed and clients are allowed
-	 * to ignore the `percentage` value in subsequent in report notifications.
-	 *
-	 * The value should be steadily rising. Clients are free to ignore values
-	 * that are not following this rule. The value range is [0, 100]
-	 */
-	percentage?: uinteger;
-}
-```
-
-##### <a href="#workDoneProgressReport" name="workDoneProgressReport" class="anchor"> Work Done Progress Report </a>
-
-Reporting progress is done using the following payload:
-
-```typescript
-export interface WorkDoneProgressReport {
-
-	kind: 'report';
-
-	/**
-	 * Controls enablement state of a cancel button. This property is only valid
-	 * if a cancel button got requested in the `WorkDoneProgressBegin` payload.
-	 *
-	 * Clients that don't support cancellation or don't support control the
-	 * button's enablement state are allowed to ignore the setting.
-	 */
-	cancellable?: boolean;
-
-	/**
-	 * Optional, more detailed associated progress message. Contains
-	 * complementary information to the `title`.
-	 *
-	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
-	 * If unset, the previous progress message (if any) is still valid.
-	 */
-	message?: string;
-
-	/**
-	 * Optional progress percentage to display (value 100 is considered 100%).
-	 * If not provided infinite progress is assumed and clients are allowed
-	 * to ignore the `percentage` value in subsequent in report notifications.
-	 *
-	 * The value should be steadily rising. Clients are free to ignore values
-	 * that are not following this rule. The value range is [0, 100]
-	 */
-	percentage?: uinteger;
-}
-```
-
-##### <a href="#workDoneProgressEnd" name="workDoneProgressEnd" class="anchor"> Work Done Progress End </a>
-
-Signaling the end of a progress reporting is done using the following payload:
-
-```typescript
-export interface WorkDoneProgressEnd {
-
-	kind: 'end';
-
-	/**
-	 * Optional, a final message indicating to for example indicate the outcome
-	 * of the operation.
-	 */
-	message?: string;
-}
-```
-
-##### <a href="#initiatingWorkDoneProgress" name="initiatingWorkDoneProgress" class="anchor"> Initiating Work Done Progress </a>
-
-Work Done progress can be initiated in two different ways:
-
-1. by the sender of a request (mostly clients) using the predefined `workDoneToken` property in the requests parameter literal. The document will refer to this kind of progress as client initiated progress.
-1. by a server using the request `window/workDoneProgress/create`. The document will refer to this kind of progress as server initiated progress.
-
-###### <a href="#clientInitiatedProgress" name="clientInitiatedProgress" class="anchor">Client Initiated Progress </a>
-
-Consider a client sending a `textDocument/reference` request to a server and the client accepts work done progress reporting on that request. To signal this to the server the client would add a `workDoneToken` property to the reference request parameters. Something like this:
-
-```json
-{
-	"textDocument": {
-		"uri": "file:///folder/file.ts"
-	},
-	"position": {
-		"line": 9,
-		"character": 5
-	},
-	"context": {
-		"includeDeclaration": true
-	},
-	// The token used to report work done progress.
-	"workDoneToken": "1d546990-40a3-4b77-b134-46622995f6ae"
-}
-```
-
-The corresponding type definition for the parameter property looks like this:
-
-
-<div class="anchorHolder"><a href="#workDoneProgressParams" name="workDoneProgressParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkDoneProgressParams {
-	/**
-	 * An optional token that a server can use to report work done progress.
-	 */
-	workDoneToken?: ProgressToken;
-}
-```
-
-A server uses the `workDoneToken` to report progress for the specific `textDocument/reference`. For the above request the `$/progress` notification params look like this:
-
-```json
-{
-	"token": "1d546990-40a3-4b77-b134-46622995f6ae",
-	"value": {
-		"kind": "begin",
-		"title": "Finding references for A#foo",
-		"cancellable": false,
-		"message": "Processing file X.ts",
-		"percentage": 0
-	}
-}
-```
-
-The token received via the `workDoneToken` property in a request's param literal is only valid as long as the request has not send a response back.
-
-There is no specific client capability signaling whether a client will send a progress token per request. The reason for this is that this is in many clients not a static aspect and might even change for every request instance for the same request type. So the capability is signal on every request instance by the presence of a `workDoneToken` property.
-
-To avoid that clients set up a progress monitor user interface before sending a request but the server doesn't actually report any progress a server needs to signal general work done progress reporting support in the corresponding server capability. For the above find references example a server would signal such a support by setting the `referencesProvider` property in the server capabilities as follows:
-
-```json
-{
-	"referencesProvider": {
-		"workDoneProgress": true
-	}
-}
-```
-
-The corresponding type definition for the server capability looks like this:
-
-<div class="anchorHolder"><a href="#workDoneProgressOptions" name="workDoneProgressOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkDoneProgressOptions {
-	workDoneProgress?: boolean;
-}
-```
-###### <a href="#serverInitiatedProgress" name="serverInitiatedProgress" class="anchor">Server Initiated Progress </a>
-
-Servers can also initiate progress reporting using the `window/workDoneProgress/create` request. This is useful if the server needs to report progress outside of a request (for example the server needs to re-index a database). The token can then be used to report progress using the same notifications used as for client initiated progress. The token provided in the create request should only be used once (e.g. only one begin, many report and one end notification should be sent to it).
-
-To keep the protocol backwards compatible servers are only allowed to use `window/workDoneProgress/create` request if the client signals corresponding support using the client capability `window.workDoneProgress` which is defined as follows:
-
-```typescript
-	/**
-	 * Window specific client capabilities.
-	 */
-	window?: {
-		/**
-		 * Whether client supports server initiated progress using the
-		 * `window/workDoneProgress/create` request.
-		 */
-		workDoneProgress?: boolean;
-	};
-```
-#### <a href="#partialResults" name="partialResults" class="anchor"> Partial Result Progress </a>
-
-> *Since version 3.15.0*
-
-Partial results are also reported using the generic [`$/progress`](#progress) notification. The value payload of a partial result progress notification is in most cases the same as the final result. For example the `workspace/symbol` request has `SymbolInformation[]` \| `WorkspaceSymbol[]` as the result type. Partial result is therefore also of type `SymbolInformation[]` \| `WorkspaceSymbol[]`. Whether a client accepts partial result notifications for a request is signaled by adding a `partialResultToken` to the request parameter. For example, a `textDocument/reference` request that supports both work done and partial result progress might look like this:
-
-```json
-{
-	"textDocument": {
-		"uri": "file:///folder/file.ts"
-	},
-	"position": {
-		"line": 9,
-		"character": 5
-	},
-	"context": {
-		"includeDeclaration": true
-	},
-	// The token used to report work done progress.
-	"workDoneToken": "1d546990-40a3-4b77-b134-46622995f6ae",
-	// The token used to report partial result progress.
-	"partialResultToken": "5f6f349e-4f81-4a3b-afff-ee04bff96804"
-}
-```
-
-The `partialResultToken` is then used to report partial results for the find references request.
-
-If a server reports partial result via a corresponding `$/progress`, the whole result must be reported using n `$/progress` notifications. The final response has to be empty in terms of result values. This avoids confusion about how the final result should be interpreted, e.g. as another partial result or as a replacing result.
-
-If the response errors the provided partial results should be treated as follows:
-
-- the `code` equals to `RequestCancelled`: the client is free to use the provided results but should make clear that the request got canceled and may be incomplete.
-- in all other cases the provided partial results shouldn't be used.
-#### <a href="#partialResultParams" name="partialResultParams" class="anchor"> PartialResultParams </a>
-
-A parameter literal used to pass a partial result token.
-
-```typescript
-export interface PartialResultParams {
-	/**
-	 * An optional token that a server can use to report partial results (e.g.
-	 * streaming) to the client.
-	 */
-	partialResultToken?: ProgressToken;
-}
-```
-#### <a href="#traceValue" name="traceValue" class="anchor"> TraceValue </a>
-
-A `TraceValue` represents the level of verbosity with which the server systematically reports its execution trace using [$/logTrace](#logTrace) notifications.
-The initial trace value is set by the client at initialization and can be modified later using the [$/setTrace](#setTrace) notification.
-
-```typescript
-export type TraceValue = 'off' | 'messages' | 'verbose';
-```
-
-### <a href="#lifeCycleMessages" name="lifeCycleMessages" class="anchor"> Server lifecycle </a>
-
-The current protocol specification defines that the lifecycle of a server is managed by the client (e.g. a tool like VS Code or Emacs). It is up to the client to decide when to start (process-wise) and when to shutdown a server.
-
-#### <a href="#initialize" name="initialize" class="anchor">Initialize Request (:leftwards_arrow_with_hook:)</a>
-
-The initialize request is sent as the first request from the client to the server. If the server receives a request or notification before the `initialize` request it should act as follows:
-
-* For a request the response should be an error with `code: -32002`. The message can be picked by the server.
-* Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.
-
-Until the server has responded to the `initialize` request with an `InitializeResult`, the client must not send any additional requests or notifications to the server. In addition the server is not allowed to send any requests or notifications to the client until it has responded with an `InitializeResult`, with the exception that during the `initialize` request the server is allowed to send the notifications `window/showMessage`, `window/logMessage` and `telemetry/event` as well as the `window/showMessageRequest` request to the client. In case the client sets up a progress token in the initialize params (e.g. property `workDoneToken`) the server is also allowed to use that token (and only that token) using the `$/progress` notification sent from the server to the client.
-
-The `initialize` request may only be sent once.
-
-_Request_:
-* method: 'initialize'
-* params: `InitializeParams` defined as follows:
-
-<div class="anchorHolder"><a href="#initializeParams" name="initializeParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface InitializeParams extends WorkDoneProgressParams {
-	/**
-	 * The process Id of the parent process that started the server. Is null if
-	 * the process has not been started by another process. If the parent
-	 * process is not alive then the server should exit (see exit notification)
-	 * its process.
-	 */
-	processId: integer | null;
-
-	/**
-	 * Information about the client
-	 *
-	 * @since 3.15.0
-	 */
-	clientInfo?: {
-		/**
-		 * The name of the client as defined by the client.
-		 */
-		name: string;
-
-		/**
-		 * The client's version as defined by the client.
-		 */
-		version?: string;
-	};
-
-	/**
-	 * The locale the client is currently showing the user interface
-	 * in. This must not necessarily be the locale of the operating
-	 * system.
-	 *
-	 * Uses IETF language tags as the value's syntax
-	 * (See https://en.wikipedia.org/wiki/IETF_language_tag)
-	 *
-	 * @since 3.16.0
-	 */
-	locale?: string;
-
-	/**
-	 * The rootPath of the workspace. Is null
-	 * if no folder is open.
-	 *
-	 * @deprecated in favour of `rootUri`.
-	 */
-	rootPath?: string | null;
-
-	/**
-	 * The rootUri of the workspace. Is null if no
-	 * folder is open. If both `rootPath` and `rootUri` are set
-	 * `rootUri` wins.
-	 *
-	 * @deprecated in favour of `workspaceFolders`
-	 */
-	rootUri: DocumentUri | null;
-
-	/**
-	 * User provided initialization options.
-	 */
-	initializationOptions?: LSPAny;
-
-	/**
-	 * The capabilities provided by the client (editor or tool)
-	 */
-	capabilities: ClientCapabilities;
-
-	/**
-	 * The initial trace setting. If omitted trace is disabled ('off').
-	 */
-	trace?: TraceValue;
-
-	/**
-	 * The workspace folders configured in the client when the server starts.
-	 * This property is only available if the client supports workspace folders.
-	 * It can be `null` if the client supports workspace folders but none are
-	 * configured.
-	 *
-	 * @since 3.6.0
-	 */
-	workspaceFolders?: WorkspaceFolder[] | null;
-}
-```
-Where `ClientCapabilities` and `TextDocumentClientCapabilities` are defined as follows:
-
-
-##### TextDocumentClientCapabilities
-
-`TextDocumentClientCapabilities` define capabilities the editor / tool provides on text documents.
-
-<div class="anchorHolder"><a href="#textDocumentClientCapabilities" name="textDocumentClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Text document specific client capabilities.
- */
-export interface TextDocumentClientCapabilities {
-
-	synchronization?: TextDocumentSyncClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/completion` request.
-	 */
-	completion?: CompletionClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/hover` request.
-	 */
-	hover?: HoverClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/signatureHelp` request.
-	 */
-	signatureHelp?: SignatureHelpClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/declaration` request.
-	 *
-	 * @since 3.14.0
-	 */
-	declaration?: DeclarationClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/definition` request.
-	 */
-	definition?: DefinitionClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/typeDefinition` request.
-	 *
-	 * @since 3.6.0
-	 */
-	typeDefinition?: TypeDefinitionClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/implementation` request.
-	 *
-	 * @since 3.6.0
-	 */
-	implementation?: ImplementationClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/references` request.
-	 */
-	references?: ReferenceClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/documentHighlight` request.
-	 */
-	documentHighlight?: DocumentHighlightClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/documentSymbol` request.
-	 */
-	documentSymbol?: DocumentSymbolClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/codeAction` request.
-	 */
-	codeAction?: CodeActionClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/codeLens` request.
-	 */
-	codeLens?: CodeLensClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/documentLink` request.
-	 */
-	documentLink?: DocumentLinkClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/documentColor` and the
-	 * `textDocument/colorPresentation` request.
-	 *
-	 * @since 3.6.0
-	 */
-	colorProvider?: DocumentColorClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/formatting` request.
-	 */
-	formatting?: DocumentFormattingClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/rangeFormatting` request.
-	 */
-	rangeFormatting?: DocumentRangeFormattingClientCapabilities;
-
-	/** request.
-	 * Capabilities specific to the `textDocument/onTypeFormatting` request.
-	 */
-	onTypeFormatting?: DocumentOnTypeFormattingClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/rename` request.
-	 */
-	rename?: RenameClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/publishDiagnostics`
-	 * notification.
-	 */
-	publishDiagnostics?: PublishDiagnosticsClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/foldingRange` request.
-	 *
-	 * @since 3.10.0
-	 */
-	foldingRange?: FoldingRangeClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/selectionRange` request.
-	 *
-	 * @since 3.15.0
-	 */
-	selectionRange?: SelectionRangeClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/linkedEditingRange` request.
-	 *
-	 * @since 3.16.0
-	 */
-	linkedEditingRange?: LinkedEditingRangeClientCapabilities;
-
-	/**
-	 * Capabilities specific to the various call hierarchy requests.
-	 *
-	 * @since 3.16.0
-	 */
-	callHierarchy?: CallHierarchyClientCapabilities;
-
-	/**
-	 * Capabilities specific to the various semantic token requests.
-	 *
-	 * @since 3.16.0
-	 */
-	semanticTokens?: SemanticTokensClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/moniker` request.
-	 *
-	 * @since 3.16.0
-	 */
-	moniker?: MonikerClientCapabilities;
-
-	/**
-	 * Capabilities specific to the various type hierarchy requests.
-	 *
-	 * @since 3.17.0
-	 */
-	typeHierarchy?: TypeHierarchyClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/inlineValue` request.
-	 *
-	 * @since 3.17.0
-	 */
-	inlineValue?: InlineValueClientCapabilities;
-
-	/**
-	 * Capabilities specific to the `textDocument/inlayHint` request.
-	 *
-	 * @since 3.17.0
-	 */
-	inlayHint?: InlayHintClientCapabilities;
-
-	/**
-	 * Capabilities specific to the diagnostic pull model.
-	 *
-	 * @since 3.17.0
-	 */
-	diagnostic?: DiagnosticClientCapabilities;
-}
-```
-
-##### NotebookDocumentClientCapabilities
-
-`NotebookDocumentClientCapabilities` define capabilities the editor / tool provides on notebook documents.
-
-<div class="anchorHolder"><a href="#notebookDocumentClientCapabilities" name="notebookDocumentClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Capabilities specific to the notebook document support.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentClientCapabilities {
-	/**
-	 * Capabilities specific to notebook document synchronization
-	 *
-	 * @since 3.17.0
-	 */
-	synchronization: NotebookDocumentSyncClientCapabilities;
-}
-```
-
-
-`ClientCapabilities` define capabilities for dynamic registration, workspace and text document features the client supports. The `experimental` can be used to pass experimental capabilities under development. For future compatibility a `ClientCapabilities` object literal can have more properties set than currently defined. Servers receiving a `ClientCapabilities` object literal with unknown properties should ignore these properties. A missing property should be interpreted as an absence of the capability. If a missing property normally defines sub properties, all missing sub properties should be interpreted as an absence of the corresponding capability.
-
-Client capabilities got introduced with version 3.0 of the protocol. They therefore only describe capabilities that got introduced in 3.x or later. Capabilities that existed in the 2.x version of the protocol are still mandatory for clients. Clients cannot opt out of providing them. So even if a client omits the `ClientCapabilities.textDocument.synchronization` it is still required that the client provides text document synchronization (e.g. open, changed and close notifications).
-
-<div class="anchorHolder"><a href="#clientCapabilities" name="clientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-interface ClientCapabilities {
-	/**
-	 * Workspace specific client capabilities.
-	 */
-	workspace?: {
-		/**
-		 * The client supports applying batch edits
-		 * to the workspace by supporting the request
-		 * 'workspace/applyEdit'
-		 */
-		applyEdit?: boolean;
-
-		/**
-		 * Capabilities specific to `WorkspaceEdit`s
-		 */
-		workspaceEdit?: WorkspaceEditClientCapabilities;
-
-		/**
-		 * Capabilities specific to the `workspace/didChangeConfiguration`
-		 * notification.
-		 */
-		didChangeConfiguration?: DidChangeConfigurationClientCapabilities;
-
-		/**
-		 * Capabilities specific to the `workspace/didChangeWatchedFiles`
-		 * notification.
-		 */
-		didChangeWatchedFiles?: DidChangeWatchedFilesClientCapabilities;
-
-		/**
-		 * Capabilities specific to the `workspace/symbol` request.
-		 */
-		symbol?: WorkspaceSymbolClientCapabilities;
-
-		/**
-		 * Capabilities specific to the `workspace/executeCommand` request.
-		 */
-		executeCommand?: ExecuteCommandClientCapabilities;
-
-		/**
-		 * The client has support for workspace folders.
-		 *
-		 * @since 3.6.0
-		 */
-		workspaceFolders?: boolean;
-
-		/**
-		 * The client supports `workspace/configuration` requests.
-		 *
-		 * @since 3.6.0
-		 */
-		configuration?: boolean;
-
-		/**
-		 * Capabilities specific to the semantic token requests scoped to the
-		 * workspace.
-		 *
-		 * @since 3.16.0
-		 */
-		 semanticTokens?: SemanticTokensWorkspaceClientCapabilities;
-
-		/**
-		 * Capabilities specific to the code lens requests scoped to the
-		 * workspace.
-		 *
-		 * @since 3.16.0
-		 */
-		codeLens?: CodeLensWorkspaceClientCapabilities;
-
-		/**
-		 * The client has support for file requests/notifications.
-		 *
-		 * @since 3.16.0
-		 */
-		fileOperations?: {
-			/**
-			 * Whether the client supports dynamic registration for file
-			 * requests/notifications.
-			 */
-			dynamicRegistration?: boolean;
-
-			/**
-			 * The client has support for sending didCreateFiles notifications.
-			 */
-			didCreate?: boolean;
-
-			/**
-			 * The client has support for sending willCreateFiles requests.
-			 */
-			willCreate?: boolean;
-
-			/**
-			 * The client has support for sending didRenameFiles notifications.
-			 */
-			didRename?: boolean;
-
-			/**
-			 * The client has support for sending willRenameFiles requests.
-			 */
-			willRename?: boolean;
-
-			/**
-			 * The client has support for sending didDeleteFiles notifications.
-			 */
-			didDelete?: boolean;
-
-			/**
-			 * The client has support for sending willDeleteFiles requests.
-			 */
-			willDelete?: boolean;
-		};
-
-		/**
-		 * Client workspace capabilities specific to inline values.
-		 *
-		 * @since 3.17.0
-		 */
-		inlineValue?: InlineValueWorkspaceClientCapabilities;
-
-		/**
-		 * Client workspace capabilities specific to inlay hints.
-		 *
-		 * @since 3.17.0
-		 */
-		inlayHint?: InlayHintWorkspaceClientCapabilities;
-
-		/**
-		 * Client workspace capabilities specific to diagnostics.
-		 *
-		 * @since 3.17.0.
-		 */
-		diagnostics?: DiagnosticWorkspaceClientCapabilities;
-	};
-
-	/**
-	 * Text document specific client capabilities.
-	 */
-	textDocument?: TextDocumentClientCapabilities;
-
-	/**
-	 * Capabilities specific to the notebook document support.
-	 *
-	 * @since 3.17.0
-	 */
-	notebookDocument?: NotebookDocumentClientCapabilities;
-
-	/**
-	 * Window specific client capabilities.
-	 */
-	window?: {
-		/**
-		 * It indicates whether the client supports server initiated
-		 * progress using the `window/workDoneProgress/create` request.
-		 *
-		 * The capability also controls Whether client supports handling
-		 * of progress notifications. If set servers are allowed to report a
-		 * `workDoneProgress` property in the request specific server
-		 * capabilities.
-		 *
-		 * @since 3.15.0
-		 */
-		workDoneProgress?: boolean;
-
-		/**
-		 * Capabilities specific to the showMessage request
-		 *
-		 * @since 3.16.0
-		 */
-		showMessage?: ShowMessageRequestClientCapabilities;
-
-		/**
-		 * Client capabilities for the show document request.
-		 *
-		 * @since 3.16.0
-		 */
-		showDocument?: ShowDocumentClientCapabilities;
-	};
-
-	/**
-	 * General client capabilities.
-	 *
-	 * @since 3.16.0
-	 */
-	general?: {
-		/**
-		 * Client capability that signals how the client
-		 * handles stale requests (e.g. a request
-		 * for which the client will not process the response
-		 * anymore since the information is outdated).
-		 *
-		 * @since 3.17.0
-		 */
-		staleRequestSupport?: {
-			/**
-			 * The client will actively cancel the request.
-			 */
-			cancel: boolean;
-
-			/**
-			 * The list of requests for which the client
-			 * will retry the request if it receives a
-			 * response with error code `ContentModified``
-			 */
-			 retryOnContentModified: string[];
-		}
-
-		/**
-		 * Client capabilities specific to regular expressions.
-		 *
-		 * @since 3.16.0
-		 */
-		regularExpressions?: RegularExpressionsClientCapabilities;
-
-		/**
-		 * Client capabilities specific to the client's markdown parser.
-		 *
-		 * @since 3.16.0
-		 */
-		markdown?: MarkdownClientCapabilities;
-
-		/**
-		 * The position encodings supported by the client. Client and server
-		 * have to agree on the same position encoding to ensure that offsets
-		 * (e.g. character position in a line) are interpreted the same on both
-		 * side.
-		 *
-		 * To keep the protocol backwards compatible the following applies: if
-		 * the value 'utf-16' is missing from the array of position encodings
-		 * servers can assume that the client supports UTF-16. UTF-16 is
-		 * therefore a mandatory encoding.
-		 *
-		 * If omitted it defaults to ['utf-16'].
-		 *
-		 * Implementation considerations: since the conversion from one encoding
-		 * into another requires the content of the file / line the conversion
-		 * is best done where the file is read which is usually on the server
-		 * side.
-		 *
-		 * @since 3.17.0
-		 */
-		positionEncodings?: PositionEncodingKind[];
-	};
-
-	/**
-	 * Experimental client capabilities.
-	 */
-	experimental?: LSPAny;
-}
-```
-
-_Response_:
-* result: `InitializeResult` defined as follows:
-
-<div class="anchorHolder"><a href="#initializeResult" name="initializeResult" class="linkableAnchor"></a></div>
-
-```typescript
-interface InitializeResult {
-	/**
-	 * The capabilities the language server provides.
-	 */
-	capabilities: ServerCapabilities;
-
-	/**
-	 * Information about the server.
-	 *
-	 * @since 3.15.0
-	 */
-	serverInfo?: {
-		/**
-		 * The name of the server as defined by the server.
-		 */
-		name: string;
-
-		/**
-		 * The server's version as defined by the server.
-		 */
-		version?: string;
-	};
-}
-```
-* error.code:
-
-<div class="anchorHolder"><a href="#initializeErrorCodes" name="initializeErrorCodes" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Known error codes for an `InitializeErrorCodes`;
- */
-export namespace InitializeErrorCodes {
-
-	/**
-	 * If the protocol version provided by the client can't be handled by
-	 * the server.
-	 *
-	 * @deprecated This initialize error got replaced by client capabilities.
-	 * There is no version handshake in version 3.0x
-	 */
-	export const unknownProtocolVersion: 1 = 1;
-}
-
-export type InitializeErrorCodes = 1;
-```
-
-* error.data:
-
-<div class="anchorHolder"><a href="#initializeError" name="initializeError" class="linkableAnchor"></a></div>
-
-```typescript
-interface InitializeError {
-	/**
-	 * Indicates whether the client execute the following retry logic:
-	 * (1) show the message provided by the ResponseError to the user
-	 * (2) user selects retry or cancel
-	 * (3) if user selected retry the initialize method is sent again.
-	 */
-	retry: boolean;
-}
-```
-
-The server can signal the following capabilities:
-
-<div class="anchorHolder"><a href="#serverCapabilities" name="serverCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-interface ServerCapabilities {
-
-	/**
-	 * The position encoding the server picked from the encodings offered
-	 * by the client via the client capability `general.positionEncodings`.
-	 *
-	 * If the client didn't provide any position encodings the only valid
-	 * value that a server can return is 'utf-16'.
-	 *
-	 * If omitted it defaults to 'utf-16'.
-	 *
-	 * @since 3.17.0
-	 */
-	positionEncoding?: PositionEncodingKind;
-
-	/**
-	 * Defines how text documents are synced. Is either a detailed structure
-	 * defining each notification or for backwards compatibility the
-	 * TextDocumentSyncKind number. If omitted it defaults to
-	 * `TextDocumentSyncKind.None`.
-	 */
-	textDocumentSync?: TextDocumentSyncOptions | TextDocumentSyncKind;
-
-	/**
-	 * Defines how notebook documents are synced.
-	 *
-	 * @since 3.17.0
-	 */
-	notebookDocumentSync?: NotebookDocumentSyncOptions
-		| NotebookDocumentSyncRegistrationOptions;
-
-	/**
-	 * The server provides completion support.
-	 */
-	completionProvider?: CompletionOptions;
-
-	/**
-	 * The server provides hover support.
-	 */
-	hoverProvider?: boolean | HoverOptions;
-
-	/**
-	 * The server provides signature help support.
-	 */
-	signatureHelpProvider?: SignatureHelpOptions;
-
-	/**
-	 * The server provides go to declaration support.
-	 *
-	 * @since 3.14.0
-	 */
-	declarationProvider?: boolean | DeclarationOptions
-		| DeclarationRegistrationOptions;
-
-	/**
-	 * The server provides goto definition support.
-	 */
-	definitionProvider?: boolean | DefinitionOptions;
-
-	/**
-	 * The server provides goto type definition support.
-	 *
-	 * @since 3.6.0
-	 */
-	typeDefinitionProvider?: boolean | TypeDefinitionOptions
-		| TypeDefinitionRegistrationOptions;
-
-	/**
-	 * The server provides goto implementation support.
-	 *
-	 * @since 3.6.0
-	 */
-	implementationProvider?: boolean | ImplementationOptions
-		| ImplementationRegistrationOptions;
-
-	/**
-	 * The server provides find references support.
-	 */
-	referencesProvider?: boolean | ReferenceOptions;
-
-	/**
-	 * The server provides document highlight support.
-	 */
-	documentHighlightProvider?: boolean | DocumentHighlightOptions;
-
-	/**
-	 * The server provides document symbol support.
-	 */
-	documentSymbolProvider?: boolean | DocumentSymbolOptions;
-
-	/**
-	 * The server provides code actions. The `CodeActionOptions` return type is
-	 * only valid if the client signals code action literal support via the
-	 * property `textDocument.codeAction.codeActionLiteralSupport`.
-	 */
-	codeActionProvider?: boolean | CodeActionOptions;
-
-	/**
-	 * The server provides code lens.
-	 */
-	codeLensProvider?: CodeLensOptions;
-
-	/**
-	 * The server provides document link support.
-	 */
-	documentLinkProvider?: DocumentLinkOptions;
-
-	/**
-	 * The server provides color provider support.
-	 *
-	 * @since 3.6.0
-	 */
-	colorProvider?: boolean | DocumentColorOptions
-		| DocumentColorRegistrationOptions;
-
-	/**
-	 * The server provides document formatting.
-	 */
-	documentFormattingProvider?: boolean | DocumentFormattingOptions;
-
-	/**
-	 * The server provides document range formatting.
-	 */
-	documentRangeFormattingProvider?: boolean | DocumentRangeFormattingOptions;
-
-	/**
-	 * The server provides document formatting on typing.
-	 */
-	documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;
-
-	/**
-	 * The server provides rename support. RenameOptions may only be
-	 * specified if the client states that it supports
-	 * `prepareSupport` in its initial `initialize` request.
-	 */
-	renameProvider?: boolean | RenameOptions;
-
-	/**
-	 * The server provides folding provider support.
-	 *
-	 * @since 3.10.0
-	 */
-	foldingRangeProvider?: boolean | FoldingRangeOptions
-		| FoldingRangeRegistrationOptions;
-
-	/**
-	 * The server provides execute command support.
-	 */
-	executeCommandProvider?: ExecuteCommandOptions;
-
-	/**
-	 * The server provides selection range support.
-	 *
-	 * @since 3.15.0
-	 */
-	selectionRangeProvider?: boolean | SelectionRangeOptions
-		| SelectionRangeRegistrationOptions;
-
-	/**
-	 * The server provides linked editing range support.
-	 *
-	 * @since 3.16.0
-	 */
-	linkedEditingRangeProvider?: boolean | LinkedEditingRangeOptions
-		| LinkedEditingRangeRegistrationOptions;
-
-	/**
-	 * The server provides call hierarchy support.
-	 *
-	 * @since 3.16.0
-	 */
-	callHierarchyProvider?: boolean | CallHierarchyOptions
-		| CallHierarchyRegistrationOptions;
-
-	/**
-	 * The server provides semantic tokens support.
-	 *
-	 * @since 3.16.0
-	 */
-	semanticTokensProvider?: SemanticTokensOptions
-		| SemanticTokensRegistrationOptions;
-
-	/**
-	 * Whether server provides moniker support.
-	 *
-	 * @since 3.16.0
-	 */
-	monikerProvider?: boolean | MonikerOptions | MonikerRegistrationOptions;
-
-	/**
-	 * The server provides type hierarchy support.
-	 *
-	 * @since 3.17.0
-	 */
-	typeHierarchyProvider?: boolean | TypeHierarchyOptions
-		 | TypeHierarchyRegistrationOptions;
-
-	/**
-	 * The server provides inline values.
-	 *
-	 * @since 3.17.0
-	 */
-	inlineValueProvider?: boolean | InlineValueOptions
-		 | InlineValueRegistrationOptions;
-
-	/**
-	 * The server provides inlay hints.
-	 *
-	 * @since 3.17.0
-	 */
-	inlayHintProvider?: boolean | InlayHintOptions
-		 | InlayHintRegistrationOptions;
-
-	/**
-	 * The server has support for pull model diagnostics.
-	 *
-	 * @since 3.17.0
-	 */
-	diagnosticProvider?: DiagnosticOptions | DiagnosticRegistrationOptions;
-
-	/**
-	 * The server provides workspace symbol support.
-	 */
-	workspaceSymbolProvider?: boolean | WorkspaceSymbolOptions;
-
-	/**
-	 * Workspace specific server capabilities
-	 */
-	workspace?: {
-		/**
-		 * The server supports workspace folder.
-		 *
-		 * @since 3.6.0
-		 */
-		workspaceFolders?: WorkspaceFoldersServerCapabilities;
-
-		/**
-		 * The server is interested in file notifications/requests.
-		 *
-		 * @since 3.16.0
-		 */
-		fileOperations?: {
-			/**
-			 * The server is interested in receiving didCreateFiles
-			 * notifications.
-			 */
-			didCreate?: FileOperationRegistrationOptions;
-
-			/**
-			 * The server is interested in receiving willCreateFiles requests.
-			 */
-			willCreate?: FileOperationRegistrationOptions;
-
-			/**
-			 * The server is interested in receiving didRenameFiles
-			 * notifications.
-			 */
-			didRename?: FileOperationRegistrationOptions;
-
-			/**
-			 * The server is interested in receiving willRenameFiles requests.
-			 */
-			willRename?: FileOperationRegistrationOptions;
-
-			/**
-			 * The server is interested in receiving didDeleteFiles file
-			 * notifications.
-			 */
-			didDelete?: FileOperationRegistrationOptions;
-
-			/**
-			 * The server is interested in receiving willDeleteFiles file
-			 * requests.
-			 */
-			willDelete?: FileOperationRegistrationOptions;
-		};
-	};
-
-	/**
-	 * Experimental server capabilities.
-	 */
-	experimental?: LSPAny;
-}
-```
-
-#### <a href="#initialized" name="initialized" class="anchor">Initialized Notification (:arrow_right:)</a>
-
-The initialized notification is sent from the client to the server after the client received the result of the `initialize` request but before the client is sending any other request or notification to the server. The server can use the `initialized` notification for example to dynamically register capabilities. The `initialized` notification may only be sent once.
-
-_Notification_:
-* method: 'initialized'
-* params: `InitializedParams` defined as follows:
-
-```typescript
-interface InitializedParams {
-}
-```
-
-#### <a href="#client_registerCapability" name="client_registerCapability" class="anchor">Register Capability (:arrow_right_hook:)</a>
-
-The `client/registerCapability` request is sent from the server to the client to register for a new capability on the client side. Not all clients need to support dynamic capability registration. A client opts in via the `dynamicRegistration` property on the specific client capabilities. A client can even provide dynamic registration for capability A but not for capability B (see `TextDocumentClientCapabilities` as an example).
-
-Server must not register the same capability both statically through the initialize result and dynamically for the same document selector. If a server wants to support both static and dynamic registration it needs to check the client capability in the initialize request and only register the capability statically if the client doesn't support dynamic registration for that capability.
-
-_Request_:
-* method: 'client/registerCapability'
-* params: `RegistrationParams`
-
-Where `RegistrationParams` are defined as follows:
-
-<div class="anchorHolder"><a href="#registration" name="registration" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * General parameters to register for a capability.
- */
-export interface Registration {
-	/**
-	 * The id used to register the request. The id can be used to deregister
-	 * the request again.
-	 */
-	id: string;
-
-	/**
-	 * The method / capability to register for.
-	 */
-	method: string;
-
-	/**
-	 * Options necessary for the registration.
-	 */
-	registerOptions?: LSPAny;
-}
-```
-
-<div class="anchorHolder"><a href="#registrationParams" name="registrationParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface RegistrationParams {
-	registrations: Registration[];
-}
-```
-
-Since most of the registration options require to specify a document selector there is a base interface that can be used. See `TextDocumentRegistrationOptions`.
-
-An example JSON-RPC message to register dynamically for the `textDocument/willSaveWaitUntil` feature on the client side is as follows (only details shown):
-
-```json
-{
-	"method": "client/registerCapability",
-	"params": {
-		"registrations": [
-			{
-				"id": "79eee87c-c409-4664-8102-e03263673f6f",
-				"method": "textDocument/willSaveWaitUntil",
-				"registerOptions": {
-					"documentSelector": [
-						{ "language": "javascript" }
-					]
-				}
-			}
-		]
-	}
-}
-```
-
-This message is sent from the server to the client and after the client has successfully executed the request further `textDocument/willSaveWaitUntil` requests for JavaScript text documents are sent from the client to the server.
-
-_Response_:
-* result: void.
-* error: code and message set in case an exception happens during the request.
-
-`StaticRegistrationOptions` can be used to register a feature in the initialize result with a given server control ID to be able to un-register the feature later on.
-
-<div class="anchorHolder"><a href="#staticRegistrationOptions" name="staticRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Static registration options to be returned in the initialize request.
- */
-export interface StaticRegistrationOptions {
-	/**
-	 * The id used to register the request. The id can be used to deregister
-	 * the request again. See also Registration#id.
-	 */
-	id?: string;
-}
-```
-
-`TextDocumentRegistrationOptions` can be used to dynamically register for requests for a set of text documents.
-
-<div class="anchorHolder"><a href="#textDocumentRegistrationOptions" name="textDocumentRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * General text document registration options.
- */
-export interface TextDocumentRegistrationOptions {
-	/**
-	 * A document selector to identify the scope of the registration. If set to
-	 * null the document selector provided on the client side will be used.
-	 */
-	documentSelector: DocumentSelector | null;
-}
-```
-#### <a href="#client_unregisterCapability" name="client_unregisterCapability" class="anchor">Unregister Capability (:arrow_right_hook:)</a>
-
-The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability.
-
-_Request_:
-* method: 'client/unregisterCapability'
-* params: `UnregistrationParams`
-
-Where `UnregistrationParams` are defined as follows:
-
-<div class="anchorHolder"><a href="#unregistration" name="unregistration" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * General parameters to unregister a capability.
- */
-export interface Unregistration {
-	/**
-	 * The id used to unregister the request or notification. Usually an id
-	 * provided during the register request.
-	 */
-	id: string;
-
-	/**
-	 * The method / capability to unregister for.
-	 */
-	method: string;
-}
-```
-
-<div class="anchorHolder"><a href="#unregistrationParams" name="unregistrationParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface UnregistrationParams {
-	// This should correctly be named `unregistrations`. However changing this
-	// is a breaking change and needs to wait until we deliver a 4.x version
-	// of the specification.
-	unregisterations: Unregistration[];
-}
-```
-
-An example JSON-RPC message to unregister the above registered `textDocument/willSaveWaitUntil` feature looks like this:
-
-```json
-{
-	"method": "client/unregisterCapability",
-	"params": {
-		"unregisterations": [
-			{
-				"id": "79eee87c-c409-4664-8102-e03263673f6f",
-				"method": "textDocument/willSaveWaitUntil"
-			}
-		]
-	}
-}
-```
-_Response_:
-* result: void.
-* error: code and message set in case an exception happens during the request.
-
-#### <a href="#setTrace" name="setTrace" class="anchor">SetTrace Notification (:arrow_right:)</a>
-
-A notification that should be used by the client to modify the trace setting of the server.
-
-_Notification_:
-* method: '$/setTrace'
-* params: `SetTraceParams` defined as follows:
-
-```typescript
-interface SetTraceParams {
-	/**
-	 * The new value that should be assigned to the trace setting.
-	 */
-	value: TraceValue;
-}
-```
-
-#### <a href="#logTrace" name="logTrace" class="anchor">LogTrace Notification (:arrow_left:)</a>
-
-A notification to log the trace of the server's execution.
-The amount and content of these notifications depends on the current `trace` configuration.
-If `trace` is `'off'`, the server should not send any `logTrace` notification.
-If `trace` is `'messages'`, the server should not add the `'verbose'` field in the `LogTraceParams`.
-
-`$/logTrace` should be used for systematic trace reporting. For single debugging messages, the server should send [`window/logMessage`](#window_logMessage) notifications.
-
-
-_Notification_:
-* method: '$/logTrace'
-* params: `LogTraceParams` defined as follows:
-
-```typescript
-interface LogTraceParams {
-	/**
-	 * The message to be logged.
-	 */
-	message: string;
-	/**
-	 * Additional information that can be computed if the `trace` configuration
-	 * is set to `'verbose'`
-	 */
-	verbose?: string;
-}
-```
-
-#### <a href="#shutdown" name="shutdown" class="anchor">Shutdown Request (:leftwards_arrow_with_hook:)</a>
-
-The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than `exit` or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the `exit` notification until they have received a response from the `shutdown` request.
-
-If a server receives requests after a shutdown request those requests should error with `InvalidRequest`.
-
-_Request_:
-* method: 'shutdown'
-* params: void
-
-_Response_:
-* result: null
-* error: code and message set in case an exception happens during shutdown request.
-
-#### <a href="#exit" name="exit" class="anchor">Exit Notification (:arrow_right:)</a>
-
-A notification to ask the server to exit its process.
-The server should exit with `success` code 0 if the shutdown request has been received before; otherwise with `error` code 1.
-
-_Notification_:
-* method: 'exit'
-* params: void
-
-
-### <a href="#textDocument_synchronization" name="textDocument_synchronization" class="anchor">Text Document Synchronization</a>
-
-Client support for `textDocument/didOpen`, `textDocument/didChange` and `textDocument/didClose` notifications is mandatory in the protocol and clients can not opt out supporting them. This includes both full and incremental synchronization in the `textDocument/didChange` notification. In addition a server must either implement all three of them or none. Their capabilities are therefore controlled via a combined client and server capability. Opting out of text document synchronization makes only sense if the documents shown by the client are read only. Otherwise the server might receive request for documents, for which the content is managed in the client (e.g. they might have changed).
-
-<a href="#textDocument_synchronization_cc" name="textDocument_synchronization_cc" class="anchor">_Client Capability_:</a>
-* property path (optional): `textDocument.synchronization.dynamicRegistration`
-* property type: `boolean`
-
-Controls whether text document synchronization supports dynamic registration.
-
-<a href="#textDocument_synchronization_sc" name="textDocument_synchronization_sc" class="anchor">_Server Capability_:</a>
-* property path (optional): `textDocumentSync`
-* property type: `TextDocumentSyncKind | TextDocumentSyncOptions`. The below definition of the `TextDocumentSyncOptions` only covers the properties specific to the open, change and close notifications. A complete definition covering all properties can be found [here](#textDocument_didClose):
-
-<div class="anchorHolder"><a href="#textDocumentSyncKind" name="textDocumentSyncKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines how the host (editor) should sync document changes to the language
- * server.
- */
-export namespace TextDocumentSyncKind {
-	/**
-	 * Documents should not be synced at all.
-	 */
-	export const None = 0;
-
-	/**
-	 * Documents are synced by always sending the full content
-	 * of the document.
-	 */
-	export const Full = 1;
-
-	/**
-	 * Documents are synced by sending the full content on open.
-	 * After that only incremental updates to the document are
-	 * send.
-	 */
-	export const Incremental = 2;
-}
-```
-
-<div class="anchorHolder"><a href="#textDocumentSyncOptions" name="textDocumentSyncOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TextDocumentSyncOptions {
-	/**
-	 * Open and close notifications are sent to the server. If omitted open
-	 * close notification should not be sent.
-	 */
-	openClose?: boolean;
-
-	/**
-	 * Change notifications are sent to the server. See
-	 * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
-	 * TextDocumentSyncKind.Incremental. If omitted it defaults to
-	 * TextDocumentSyncKind.None.
-	 */
-	change?: TextDocumentSyncKind;
-}
-```
-
-#### <a href="#textDocument_didOpen" name="textDocument_didOpen" class="anchor">DidOpenTextDocument Notification (:arrow_right:)</a>
-
-The document open notification is sent from the client to the server to signal newly opened text documents. The document's content is now managed by the client and the server must not try to read the document's content using the document's Uri. Open in this sense means it is managed by the client. It doesn't necessarily mean that its content is presented in an editor. An open notification must not be sent more than once without a corresponding close notification send before. This means open and close notification must be balanced and the max open count for a particular textDocument is one. Note that a server's ability to fulfill requests is independent of whether a text document is open or closed.
-
-The `DidOpenTextDocumentParams` contain the language id the document is associated with. If the language id of a document changes, the client needs to send a `textDocument/didClose` to the server followed by a `textDocument/didOpen` with the new language id if the server handles the new language id as well.
-
-_Client Capability_:
-See general synchronization [client capabilities](#textDocument_synchronization_cc).
-
-_Server Capability_:
-See general synchronization [server capabilities](#textDocument_synchronization_sc).
-
-_Registration Options_: [`TextDocumentRegistrationOptions`](#textDocumentRegistrationOptions)
-
-_Notification_:
-* method: 'textDocument/didOpen'
-* params: `DidOpenTextDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didOpenTextDocumentParams" name="didOpenTextDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidOpenTextDocumentParams {
-	/**
-	 * The document that was opened.
-	 */
-	textDocument: TextDocumentItem;
-}
-```
-#### <a href="#textDocument_didChange" name="textDocument_didChange" class="anchor">DidChangeTextDocument Notification (:arrow_right:)</a>
-
-The document change notification is sent from the client to the server to signal changes to a text document. Before a client can change a text document it must claim ownership of its content using the `textDocument/didOpen` notification. In 2.0 the shape of the params has changed to include proper version numbers.
-
-_Client Capability_:
-See general synchronization [client capabilities](#textDocument_synchronization_cc).
-
-_Server Capability_:
-See general synchronization [server capabilities](#textDocument_synchronization_sc).
-
-_Registration Options_: `TextDocumentChangeRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#textDocumentChangeRegistrationOptions" name="textDocumentChangeRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Describe options to be used when registering for text document change events.
- */
-export interface TextDocumentChangeRegistrationOptions
-	extends TextDocumentRegistrationOptions {
-	/**
-	 * How documents are synced to the server. See TextDocumentSyncKind.Full
-	 * and TextDocumentSyncKind.Incremental.
-	 */
-	syncKind: TextDocumentSyncKind;
-}
-```
-
-_Notification_:
-* method: `textDocument/didChange`
-* params: `DidChangeTextDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeTextDocumentParams" name="didChangeTextDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidChangeTextDocumentParams {
-	/**
-	 * The document that did change. The version number points
-	 * to the version after all provided content changes have
-	 * been applied.
-	 */
-	textDocument: VersionedTextDocumentIdentifier;
-
-	/**
-	 * The actual content changes. The content changes describe single state
-	 * changes to the document. So if there are two content changes c1 (at
-	 * array index 0) and c2 (at array index 1) for a document in state S then
-	 * c1 moves the document from S to S' and c2 from S' to S''. So c1 is
-	 * computed on the state S and c2 is computed on the state S'.
-	 *
-	 * To mirror the content of a document using change events use the following
-	 * approach:
-	 * - start with the same initial content
-	 * - apply the 'textDocument/didChange' notifications in the order you
-	 *   receive them.
-	 * - apply the `TextDocumentContentChangeEvent`s in a single notification
-	 *   in the order you receive them.
-	 */
-	contentChanges: TextDocumentContentChangeEvent[];
-}
-```
-
-<div class="anchorHolder"><a href="#textDocumentContentChangeEvent" name="textDocumentContentChangeEvent" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * 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.
- */
-export type TextDocumentContentChangeEvent = {
-	/**
-	 * The range of the document that changed.
-	 */
-	range: Range;
-
-	/**
-	 * The optional length of the range that got replaced.
-	 *
-	 * @deprecated use range instead.
-	 */
-	rangeLength?: uinteger;
-
-	/**
-	 * The new text for the provided range.
-	 */
-	text: string;
-} | {
-	/**
-	 * The new text of the whole document.
-	 */
-	text: string;
-};
-```
-
-#### <a href="#textDocument_willSave" name="textDocument_willSave" class="anchor">WillSaveTextDocument Notification (:arrow_right:)</a>
-
-The document will save notification is sent from the client to the server before the document is actually saved. If a server has registered for open / close events clients should ensure that the document is open before a `willSave` notification is sent since clients can't change the content of a file without ownership transferal.
-
-_Client Capability_:
-* property name (optional): `textDocument.synchronization.willSave`
-* property type: `boolean`
-
-The capability indicates that the client supports `textDocument/willSave` notifications.
-
-_Server Capability_:
-* property name (optional): `textDocumentSync.willSave`
-* property type: `boolean`
-
-The capability indicates that the server is interested in `textDocument/willSave` notifications.
-
-_Registration Options_: `TextDocumentRegistrationOptions`
-
-_Notification_:
-* method: 'textDocument/willSave'
-* params: `WillSaveTextDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#willSaveTextDocumentParams" name="willSaveTextDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The parameters send in a will save text document notification.
- */
-export interface WillSaveTextDocumentParams {
-	/**
-	 * The document that will be saved.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The 'TextDocumentSaveReason'.
-	 */
-	reason: TextDocumentSaveReason;
-}
-```
-
-<div class="anchorHolder"><a href="#textDocumentSaveReason" name="textDocumentSaveReason" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents reasons why a text document is saved.
- */
-export namespace TextDocumentSaveReason {
-
-	/**
-	 * Manually triggered, e.g. by the user pressing save, by starting
-	 * debugging, or by an API call.
-	 */
-	export const Manual = 1;
-
-	/**
-	 * Automatic after a delay.
-	 */
-	export const AfterDelay = 2;
-
-	/**
-	 * When the editor lost focus.
-	 */
-	export const FocusOut = 3;
-}
-
-export type TextDocumentSaveReason = 1 | 2 | 3;
-```
-
-#### <a href="#textDocument_willSaveWaitUntil" name="textDocument_willSaveWaitUntil" class="anchor">WillSaveWaitUntilTextDocument Request (:leftwards_arrow_with_hook:)</a>
-
-The document will save request is sent from the client to the server before the document is actually saved. The request can return an array of TextEdits which will be applied to the text document before it is saved. Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request. This is done to keep the save fast and reliable.  If a server has registered for open / close events clients should ensure that the document is open before a `willSaveWaitUntil` notification is sent since clients can't change the content of a file without ownership transferal.
-
-_Client Capability_:
-* property name (optional): `textDocument.synchronization.willSaveWaitUntil`
-* property type: `boolean`
-
-The capability indicates that the client supports `textDocument/willSaveWaitUntil` requests.
-
-_Server Capability_:
-* property name (optional): `textDocumentSync.willSaveWaitUntil`
-* property type: `boolean`
-
-The capability indicates that the server is interested in `textDocument/willSaveWaitUntil` requests.
-
-_Registration Options_: `TextDocumentRegistrationOptions`
-
-_Request_:
-* method: `textDocument/willSaveWaitUntil`
-* params: `WillSaveTextDocumentParams`
-
-_Response_:
-* result:[`TextEdit[]`](#textEdit) \| `null`
-* error: code and message set in case an exception happens during the `textDocument/willSaveWaitUntil` request.
-
-#### <a href="#textDocument_didSave" name="textDocument_didSave" class="anchor">DidSaveTextDocument Notification (:arrow_right:)</a>
-
-The document save notification is sent from the client to the server when the document was saved in the client.
-
-_Client Capability_:
-* property name (optional): `textDocument.synchronization.didSave`
-* property type: `boolean`
-
-The capability indicates that the client supports `textDocument/didSave` notifications.
-
-_Server Capability_:
-* property name (optional): `textDocumentSync.save`
-* property type: `boolean | SaveOptions` where `SaveOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#saveOptions" name="saveOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SaveOptions {
-	/**
-	 * The client is supposed to include the content on save.
-	 */
-	includeText?: boolean;
-}
-```
-
-The capability indicates that the server is interested in `textDocument/didSave` notifications.
-
-_Registration Options_: `TextDocumentSaveRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#textDocumentSaveRegistrationOptions" name="textDocumentSaveRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TextDocumentSaveRegistrationOptions
-	extends TextDocumentRegistrationOptions {
-	/**
-	 * The client is supposed to include the content on save.
-	 */
-	includeText?: boolean;
-}
-```
-
-_Notification_:
-* method: `textDocument/didSave`
-* params: `DidSaveTextDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didSaveTextDocumentParams" name="didSaveTextDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidSaveTextDocumentParams {
-	/**
-	 * The document that was saved.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * Optional the content when saved. Depends on the includeText value
-	 * when the save notification was requested.
-	 */
-	text?: string;
-}
-```
-
-#### <a href="#textDocument_didClose" name="textDocument_didClose" class="anchor">DidCloseTextDocument Notification (:arrow_right:)</a>
-
-The document close notification is sent from the client to the server when the document got closed in the client. The document's master now exists where the document's Uri points to (e.g. if the document's Uri is a file Uri the master now exists on disk). As with the open notification the close notification is about managing the document's content. Receiving a close notification doesn't mean that the document was open in an editor before. A close notification requires a previous open notification to be sent. Note that a server's ability to fulfill requests is independent of whether a text document is open or closed.
-
-_Client Capability_:
-See general synchronization [client capabilities](#textDocument_synchronization_cc).
-
-_Server Capability_:
-See general synchronization [server capabilities](#textDocument_synchronization_sc).
-
-_Registration Options_: `TextDocumentRegistrationOptions`
-
-_Notification_:
-* method: `textDocument/didClose`
-* params: `DidCloseTextDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didCloseTextDocumentParams" name="didCloseTextDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidCloseTextDocumentParams {
-	/**
-	 * The document that was closed.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-#### <a href="#textDocument_didRename" name="textDocument_didRename" class="anchor">Renaming a document</a>
-
-Document renames should be signaled to a server sending a document close notification with the document's old name followed by a open notification using the document's new name. Major reason is that besides the name other attributes can change as well like the language that is associated with the document. In addition the new document could not be of interest for the server anymore.
-
-Servers can participate in a document rename by subscribing for the [`workspace/didRenameFiles`](#workspace_didRenameFiles) notification or the [`workspace/willRenameFiles`](#workspace_willRenameFiles) request.
-
-
-The final structure of the `TextDocumentSyncClientCapabilities` and the `TextDocumentSyncOptions` server options look like this
-
-<div class="anchorHolder"><a href="#textDocumentSyncClientCapabilities" name="textDocumentSyncClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TextDocumentSyncClientCapabilities {
-	/**
-	 * Whether text document synchronization supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports sending will save notifications.
-	 */
-	willSave?: boolean;
-
-	/**
-	 * The client supports sending a will save request and
-	 * waits for a response providing text edits which will
-	 * be applied to the document before it is saved.
-	 */
-	willSaveWaitUntil?: boolean;
-
-	/**
-	 * The client supports did save notifications.
-	 */
-	didSave?: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#textDocumentSyncKind" name="textDocumentSyncKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines how the host (editor) should sync document changes to the language
- * server.
- */
-export namespace TextDocumentSyncKind {
-	/**
-	 * Documents should not be synced at all.
-	 */
-	export const None = 0;
-
-	/**
-	 * Documents are synced by always sending the full content
-	 * of the document.
-	 */
-	export const Full = 1;
-
-	/**
-	 * Documents are synced by sending the full content on open.
-	 * After that only incremental updates to the document are
-	 * send.
-	 */
-	export const Incremental = 2;
-}
-
-export type TextDocumentSyncKind = 0 | 1 | 2;
-```
-
-<div class="anchorHolder"><a href="#textDocumentSyncOptions" name="textDocumentSyncOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TextDocumentSyncOptions {
-	/**
-	 * Open and close notifications are sent to the server. If omitted open
-	 * close notification should not be sent.
-	 */
-	openClose?: boolean;
-	/**
-	 * Change notifications are sent to the server. See
-	 * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
-	 * TextDocumentSyncKind.Incremental. If omitted it defaults to
-	 * TextDocumentSyncKind.None.
-	 */
-	change?: TextDocumentSyncKind;
-	/**
-	 * If present will save notifications are sent to the server. If omitted
-	 * the notification should not be sent.
-	 */
-	willSave?: boolean;
-	/**
-	 * If present will save wait until requests are sent to the server. If
-	 * omitted the request should not be sent.
-	 */
-	willSaveWaitUntil?: boolean;
-	/**
-	 * If present save notifications are sent to the server. If omitted the
-	 * notification should not be sent.
-	 */
-	save?: boolean | SaveOptions;
-}
-```
-
-### <a href="#notebookDocument_synchronization" name="notebookDocument_synchronization" class="anchor">Notebook Document Synchronization</a>
-
-Notebooks are becoming more and more popular. Adding support for them to the language server protocol allows notebook editors to reused language smarts provided by the server inside a notebook or a notebook cell, respectively. To reuse protocol parts and therefore server implementations notebooks are modeled in the following way in LSP:
-
-- *notebook document*: a collection of notebook cells typically stored in a file on disk. A notebook document has a type and can be uniquely identified using a resource URI.
-- *notebook cell*: holds the actual text content. Cells have a kind (either code or markdown). The actual text content of the cell is stored in a text document which can be synced to the server like all other text documents. Cell text documents have an URI however servers should not rely on any format for this URI since it is up to the client on how it will create these URIs. The URIs must be unique across ALL notebook cells and can therefore be used to uniquely identify a notebook cell or the cell's text document.
-
-The two concepts are defined as follows:
-
-<div class="anchorHolder"><a href="#notebookDocument" name="notebookDocument" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A notebook document.
- *
- * @since 3.17.0
- */
-export interface NotebookDocument {
-
-	/**
-	 * The notebook document's uri.
-	 */
-	uri: URI;
-
-	/**
-	 * The type of the notebook.
-	 */
-	notebookType: string;
-
-	/**
-	 * The version number of this document (it will increase after each
-	 * change, including undo/redo).
-	 */
-	version: integer;
-
-	/**
-	 * Additional metadata stored with the notebook
-	 * document.
-	 */
-	metadata?: LSPObject;
-
-	/**
-	 * The cells of a notebook.
-	 */
-	cells: NotebookCell[];
-}
-```
-
-<div class="anchorHolder"><a href="#notebookCell" name="notebookCell" class="linkableAnchor"></a></div>
-
-
-```typescript
-/**
- * A notebook cell.
- *
- * A cell's document URI must be unique across ALL notebook
- * cells and can therefore be used to uniquely identify a
- * notebook cell or the cell's text document.
- *
- * @since 3.17.0
- */
-export interface NotebookCell {
-
-	/**
-	 * The cell's kind
-	 */
-	kind: NotebookCellKind;
-
-	/**
-	 * The URI of the cell's text document
-	 * content.
-	 */
-	document: DocumentUri;
-
-	/**
-	 * Additional metadata stored with the cell.
-	 */
-	metadata?: LSPObject;
-
-	/**
-	 * Additional execution summary information
-	 * if supported by the client.
-	 */
-	executionSummary?: ExecutionSummary;
-}
-```
-
-<div class="anchorHolder"><a href="#notebookCellKind" name="notebookCellKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A notebook cell kind.
- *
- * @since 3.17.0
- */
-export namespace NotebookCellKind {
-
-	/**
-     * A markup-cell is formatted source that is used for display.
-     */
-	export const Markup: 1 = 1;
-
-	/**
-     * A code-cell is source code.
-     */
-	export const Code: 2 = 2;
-}
-```
-
-<div class="anchorHolder"><a href="#executionSummary" name="executionSummary" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ExecutionSummary {
-	/**
-	 * A strict monotonically increasing value
-	 * indicating the execution order of a cell
-	 * inside a notebook.
-	 */
-	executionOrder: uinteger;
-
-	/**
-	 * Whether the execution was successful or
-	 * not if known by the client.
-	 */
-	success?: boolean;
-}
-```
-
-Next we describe how notebooks, notebook cells and the content of a notebook cell should be synchronized to a language server.
-
-Syncing the text content of a cell is relatively easy since clients should model them as text documents. However since the URI of a notebook cell's text document should be opaque, servers can not know its scheme nor its path. However what is know is the notebook document itself. We therefore introduce a special filter for notebook cell documents:
-
-<div class="anchorHolder"><a href="#notebookCellTextDocumentFilter" name="notebookCellTextDocumentFilter" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A notebook cell text document filter denotes a cell text
- * document by different properties.
- *
- * @since 3.17.0
- */
-export interface NotebookCellTextDocumentFilter {
-	/**
-	 * 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.
-	 */
-	notebook: string | NotebookDocumentFilter;
-
-	/**
-	 * A language id like `python`.
-	 *
-	 * Will be matched against the language id of the
-	 * notebook cell document. '*' matches every language.
-	 */
-	language?: string;
-}
-```
-
-<div class="anchorHolder"><a href="#notebookDocumentFilter" name="notebookDocumentFilter" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A notebook document filter denotes a notebook document by
- * different properties.
- *
- * @since 3.17.0
- */
-export type NotebookDocumentFilter = {
-	/** The type of the enclosing notebook. */
-	notebookType: string;
-
-	/** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */
-	scheme?: string;
-
-	/** A glob pattern. */
-	pattern?: string;
-} | {
-	/** The type of the enclosing notebook. */
-	notebookType?: string;
-
-	/** A Uri [scheme](#Uri.scheme), like `file` or `untitled`.*/
-	scheme: string;
-
-	/** A glob pattern. */
-	pattern?: string;
-} | {
-	/** The type of the enclosing notebook. */
-	notebookType?: string;
-
-	/** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */
-	scheme?: string;
-
-	/** A glob pattern. */
-	pattern: string;
-};
-```
-
-Given these structures a Python cell document in a Jupyter notebook stored on disk in a folder having `books1` in its path can be identified as follows;
-
-```typescript
-{
-	notebook: {
-		scheme: 'file',
-		pattern '**/books1/**',
-		notebookType: 'jupyter-notebook'
-	},
-	language: 'python'
-}
-```
-
-A `NotebookCellTextDocumentFilter` can be used to register providers for certain requests like code complete or hover. If such a provider is registered the client will send the corresponding `textDocument/*` requests to the server using the cell text document's URI as the document URI.
-
-There are cases where simply only knowing about a cell's text content is not enough for a server to reason about the cells content and to provide good language smarts. Sometimes it is necessary to know all cells of a notebook document including the notebook document itself. Consider a notebook that has two JavaScript cells with the following content
-
-Cell one:
-
-```javascript
-function add(a, b) {
-	return a + b;
-}
-```
-
-Cell two:
-
-```javascript
-add/*<cursor>*/;
-```
-Requesting code assist in cell two at the marked cursor position should propose the function `add` which is only possible if the server knows about cell one and cell two and knows that they belong to the same notebook document.
-
-The protocol will therefore support two modes when it comes to synchronizing cell text content:
-
-* _cellContent_: in this mode only the cell text content is synchronized to the server using the standard `textDocument/did*` notification. No notebook document and no cell structure is synchronized. This mode allows for easy adoption of notebooks since servers can reuse most of it implementation logic.
-* _notebook_: in this mode the notebook document, the notebook cells and the notebook cell text content is synchronized to the server. To allow servers to create a consistent picture of a notebook document the cell text content is NOT synchronized using the standard `textDocument/did*` notifications. It is instead synchronized using special `notebook/did*` notifications. This ensures that the cell and its text content arrives on the server using one open, change or close event.
-
-To request the cell content only a normal document selector can be used. For example the selector `[{ language: 'python' }]` will synchronize Python notebook document cells to the server. However since this might synchronize unwanted documents as well a document filter can also be a `NotebookCellTextDocumentFilter`. So `{ notebook: { scheme: 'file', notebookType: 'jupyter-notebook' }, language: 'python' }` synchronizes all Python cells in a Jupyter notebook stored on disk.
-
-To synchronize the whole notebook document a server provides a `notebookDocumentSync` in its server capabilities. For example:
-
-```typescript
-{
-	notebookDocumentSync: {
-		notebookSelector: {
-			notebook: { scheme: 'file', notebookType: 'jupyter-notebook' },
-			cells: [{ language: 'python' }]
-		}
-	}
-}
-```
-Synchronizes the notebook including all Python cells to the server if the notebook is stored on disk.
-
-_Client Capability_:
-
-The following client capabilities are defined for notebook documents:
-
-* property name (optional): `notebookDocument.synchronization`
-* property type: `NotebookDocumentSyncClientCapabilities` defined as follows
-
-<div class="anchorHolder"><a href="#notebookDocumentSyncClientCapabilities" name="notebookDocumentSyncClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Notebook specific client capabilities.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentSyncClientCapabilities {
-
-	/**
-	 * Whether implementation supports dynamic registration. If this is
-	 * set to `true` the client supports the new
-	 * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports sending execution summary data per cell.
-	 */
-	executionSummarySupport?: boolean;
-}
-```
-
-_Server Capability_:
-
-The following server capabilities are defined for notebook documents:
-
-* property name (optional): `notebookDocumentSync`
-* property type: `NotebookDocumentOptions | NotebookDocumentRegistrationOptions` where `NotebookDocumentOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#notebookDocumentSyncOptions" name="notebookDocumentSyncOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Options specific to a notebook plus its cells
- * to be synced to the server.
- *
- * If a selector provider a notebook document
- * filter but no cell selector all cells of a
- * matching notebook document will be synced.
- *
- * If a selector provides no notebook document
- * filter but only a cell selector all notebook
- * document that contain at least one matching
- * cell will be synced.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentSyncOptions {
-	/**
-	 * The notebooks to be synced
-	 */
-	notebookSelector: ({
-		/**
-		 * The notebook to be synced If a string
-	 	 * value is provided it matches against the
-	     * notebook type. '*' matches every notebook.
-		 */
-		notebook: string | NotebookDocumentFilter;
-
-		/**
-		 * The cells of the matching notebook to be synced.
-		 */
-		cells?: { language: string }[];
-	} | {
-		/**
-		 * The notebook to be synced If a string
-	 	 * value is provided it matches against the
-	     * notebook type. '*' matches every notebook.
-		 */
-		notebook?: string | NotebookDocumentFilter;
-
-		/**
-		 * The cells of the matching notebook to be synced.
-		 */
-		cells: { language: string }[];
-	})[];
-
-	/**
-	 * Whether save notification should be forwarded to
-	 * the server. Will only be honored if mode === `notebook`.
-	 */
-	save?: boolean;
-}
-```
-
-_Registration Options_: `NotebookDocumentRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#notebookDocumentSyncRegistrationOptions" name="notebookDocumentSyncRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Registration options specific to a notebook.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentSyncRegistrationOptions extends
-	NotebookDocumentSyncOptions, StaticRegistrationOptions {
-}
-```
-
-#### <a href="#notebookDocument_didOpen" name="notebookDocument_didOpen" class="anchor">DidOpenNotebookDocument Notification (:arrow_right:)</a>
-
-The open notification is sent from the client to the server when a notebook document is opened. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability.
-
-_Notification_:
-
-* method: `notebookDocument/didOpen`
-* params: `DidOpenNotebookDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didOpenNotebookDocumentParams" name="didOpenNotebookDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The params sent in a open notebook document notification.
- *
- * @since 3.17.0
- */
-export interface DidOpenNotebookDocumentParams {
-
-	/**
-	 * The notebook document that got opened.
-	 */
-	notebookDocument: NotebookDocument;
-
-	/**
-	 * The text documents that represent the content
-	 * of a notebook cell.
-	 */
-	cellTextDocuments: TextDocumentItem[];
-}
-```
-
-#### <a href="#notebookDocument_didChange" name="notebookDocument_didChange" class="anchor">DidChangeNotebookDocument Notification (:arrow_right:)</a>
-
-The change notification is sent from the client to the server when a notebook document changes. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability.
-
-_Notification_:
-
-* method: `notebookDocument/didChange`
-* params: `DidChangeNotebookDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeNotebookDocumentParams" name="didChangeNotebookDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The params sent in a change notebook document notification.
- *
- * @since 3.17.0
- */
-export interface DidChangeNotebookDocumentParams {
-
-	/**
-	 * The notebook document that did change. The version number points
-	 * to the version after all provided changes have been applied.
-	 */
-	notebookDocument: VersionedNotebookDocumentIdentifier;
-
-	/**
-	 * The actual changes to the notebook document.
-	 *
-	 * The change describes single state change to the notebook document.
-	 * So it moves a notebook document, its cells and its cell text document
-	 * contents from state S to S'.
-	 *
-	 * To mirror the content of a notebook using change events use the
-	 * following approach:
-	 * - start with the same initial content
-	 * - apply the 'notebookDocument/didChange' notifications in the order
-	 *   you receive them.
-	 */
-	change: NotebookDocumentChangeEvent;
-}
-```
-
-<div class="anchorHolder"><a href="#versionedNotebookDocumentIdentifier" name="versionedNotebookDocumentIdentifier" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A versioned notebook document identifier.
- *
- * @since 3.17.0
- */
-export interface VersionedNotebookDocumentIdentifier {
-
-	/**
-	 * The version number of this notebook document.
-	 */
-	version: integer;
-
-	/**
-	 * The notebook document's uri.
-	 */
-	uri: URI;
-}
-```
-
-<div class="anchorHolder"><a href="#notebookDocumentChangeEvent" name="notebookDocumentChangeEvent" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A change event for a notebook document.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentChangeEvent {
-	/**
-	 * The changed meta data if any.
-	 */
-	metadata?: LSPObject;
-
-	/**
-	 * Changes to cells
-	 */
-	cells?: {
-		/**
-		 * Changes to the cell structure to add or
-		 * remove cells.
-		 */
-		structure?: {
-			/**
-			 * The change to the cell array.
-			 */
-			array: NotebookCellArrayChange;
-
-			/**
-			 * Additional opened cell text documents.
-			 */
-			didOpen?: TextDocumentItem[];
-
-			/**
-			 * Additional closed cell text documents.
-			 */
-			didClose?: TextDocumentIdentifier[];
-		};
-
-		/**
-		 * Changes to notebook cells properties like its
-		 * kind, execution summary or metadata.
-		 */
-		data?: NotebookCell[];
-
-		/**
-    	 * Changes to the text content of notebook cells.
-     	 */
-		textContent?: {
-			document: VersionedTextDocumentIdentifier;
-			changes: TextDocumentContentChangeEvent[];
-		}[];
-	};
-}
-```
-
-<div class="anchorHolder"><a href="#notebookCellArrayChange" name="notebookCellArrayChange" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A change describing how to move a `NotebookCell`
- * array from state S to S'.
- *
- * @since 3.17.0
- */
-export interface NotebookCellArrayChange {
-	/**
-	 * The start oftest of the cell that changed.
-	 */
-	start: uinteger;
-
-	/**
-	 * The deleted cells
-	 */
-	deleteCount: uinteger;
-
-	/**
-	 * The new cells, if any
-	 */
-	cells?: NotebookCell[];
-}
-```
-
-#### <a href="#notebookDocument_didSave" name="notebookDocument_didSave" class="anchor">DidSaveNotebookDocument Notification (:arrow_right:)</a>
-
-The save notification is sent from the client to the server when a notebook document is saved. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability.
-
-_Notification_:
-
-<div class="anchorHolder"><a href="#notebookDocument_didSave" name="notebookDocument_didSave" class="linkableAnchor"></a></div>
-
-* method: `notebookDocument/didSave`
-* params: `DidSaveNotebookDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didSaveNotebookDocumentParams" name="didSaveNotebookDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The params sent in a save notebook document notification.
- *
- * @since 3.17.0
- */
-export interface DidSaveNotebookDocumentParams {
-	/**
-	 * The notebook document that got saved.
-	 */
-	notebookDocument: NotebookDocumentIdentifier;
-}
-```
-
-#### <a href="#notebookDocument_didClose" name="notebookDocument_didClose" class="anchor">DidCloseNotebookDocument Notification (:arrow_right:)</a>
-
-The close notification is sent from the client to the server when a notebook document is closed. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability.
-
-_Notification_:
-
-<div class="anchorHolder"><a href="#notebookDocument_didClose" name="notebookDocument_didClose" class="linkableAnchor"></a></div>
-
-* method: `notebookDocument/didClose`
-* params: `DidCloseNotebookDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didCloseNotebookDocumentParams" name="didCloseNotebookDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The params sent in a close notebook document notification.
- *
- * @since 3.17.0
- */
-export interface DidCloseNotebookDocumentParams {
-
-	/**
-	 * The notebook document that got closed.
-	 */
-	notebookDocument: NotebookDocumentIdentifier;
-
-	/**
-	 * The text documents that represent the content
-	 * of a notebook cell that got closed.
-	 */
-	cellTextDocuments: TextDocumentIdentifier[];
-}
-```
-
-<div class="anchorHolder"><a href="#notebookDocumentIdentifier" name="notebookDocumentIdentifier" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A literal to identify a notebook document in the client.
- *
- * @since 3.17.0
- */
-export interface NotebookDocumentIdentifier {
-	/**
-	 * The notebook document's uri.
-	 */
-	uri: URI;
-}
-```
-
-### <a href="#languageFeatures" name="languageFeatures" class="anchor">Language Features</a>
-
-Language Feature provide the actual smarts in the language server protocol. The are usually executed on a [text document, position] tuple. The main language feature categories are:
-
-- code comprehension features like Hover or Goto Definition.
-- coding features like diagnostics, code complete or code actions.
-
-#### <a href="#textDocument_declaration" name="textDocument_declaration" class="anchor">Goto Declaration Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.14.0*
-
-The go to declaration request is sent from the client to the server to resolve the declaration location of a symbol at a given text document position.
-
-The result type [`LocationLink`](#locationLink)[] got introduced with version 3.14.0 and depends on the corresponding client capability `textDocument.declaration.linkSupport`.
-
-_Client Capability_:
-* property name (optional): `textDocument.declaration`
-* property type: `DeclarationClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#declarationClientCapabilities" name="declarationClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DeclarationClientCapabilities {
-	/**
-	 * Whether declaration supports dynamic registration. If this is set to
-	 * `true` the client supports the new `DeclarationRegistrationOptions`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports additional metadata in the form of declaration links.
-	 */
-	linkSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `declarationProvider`
-* property type: `boolean | DeclarationOptions | DeclarationRegistrationOptions` where `DeclarationOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#declarationOptions" name="declarationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DeclarationOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DeclarationRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#declarationRegistrationOptions" name="declarationRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DeclarationRegistrationOptions extends DeclarationOptions,
-	TextDocumentRegistrationOptions, StaticRegistrationOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/declaration`
-* params: `DeclarationParams` defined as follows:
-
-<div class="anchorHolder"><a href="#declarationParams" name="declarationParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DeclarationParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationLink)[] \|`null`
-* partial result: [`Location`](#location)[] \| [`LocationLink`](#locationLink)[]
-* error: code and message set in case an exception happens during the declaration request.
-
-#### <a href="#textDocument_definition" name="textDocument_definition" class="anchor">Goto Definition Request (:leftwards_arrow_with_hook:)</a>
-
-The go to definition request is sent from the client to the server to resolve the definition location of a symbol at a given text document position.
-
-The result type [`LocationLink`](#locationLink)[] got introduced with version 3.14.0 and depends on the corresponding client capability `textDocument.definition.linkSupport`.
-
-_Client Capability_:
-* property name (optional): `textDocument.definition`
-* property type: `DefinitionClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#definitionClientCapabilities" name="definitionClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DefinitionClientCapabilities {
-	/**
-	 * Whether definition supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports additional metadata in the form of definition links.
-	 *
-	 * @since 3.14.0
-	 */
-	linkSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `definitionProvider`
-* property type: `boolean | DefinitionOptions` where `DefinitionOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#definitionOptions" name="definitionOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DefinitionOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DefinitionRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#definitionRegistrationOptions" name="definitionRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DefinitionRegistrationOptions extends
-	TextDocumentRegistrationOptions, DefinitionOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/definition`
-* params: `DefinitionParams` defined as follows:
-
-<div class="anchorHolder"><a href="#definitionParams" name="definitionParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DefinitionParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationLink)[] \| `null`
-* partial result: [`Location`](#location)[] \| [`LocationLink`](#locationLink)[]
-* error: code and message set in case an exception happens during the definition request.
-
-#### <a href="#textDocument_typeDefinition" name="textDocument_typeDefinition" class="anchor">Goto Type Definition Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.6.0*
-
-The go to type definition request is sent from the client to the server to resolve the type definition location of a symbol at a given text document position.
-
-The result type [`LocationLink`](#locationLink)[] got introduced with version 3.14.0 and depends on the corresponding client capability `textDocument.typeDefinition.linkSupport`.
-
-_Client Capability_:
-* property name (optional): `textDocument.typeDefinition`
-* property type: `TypeDefinitionClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#typeDefinitionClientCapabilities" name="typeDefinitionClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeDefinitionClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `TypeDefinitionRegistrationOptions`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports additional metadata in the form of definition links.
-	 *
-	 * @since 3.14.0
-	 */
-	linkSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `typeDefinitionProvider`
-* property type: `boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions` where `TypeDefinitionOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#typeDefinitionOptions" name="typeDefinitionOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeDefinitionOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `TypeDefinitionRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#typeDefinitionRegistrationOptions" name="typeDefinitionRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeDefinitionRegistrationOptions extends
-	TextDocumentRegistrationOptions, TypeDefinitionOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/typeDefinition`
-* params: `TypeDefinitionParams` defined as follows:
-
-<div class="anchorHolder"><a href="#typeDefinitionParams" name="typeDefinitionParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeDefinitionParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationLink)[] \| `null`
-* partial result: [`Location`](#location)[] \| [`LocationLink`](#locationLink)[]
-* error: code and message set in case an exception happens during the definition request.
-
-#### <a href="#textDocument_implementation" name="textDocument_implementation" class="anchor">Goto Implementation Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.6.0*
-
-The go to implementation request is sent from the client to the server to resolve the implementation location of a symbol at a given text document position.
-
-The result type [`LocationLink`](#locationLink)[] got introduced with version 3.14.0 and depends on the corresponding client capability `textDocument.implementation.linkSupport`.
-
-_Client Capability_:
-* property name (optional): `textDocument.implementation`
-* property type: `ImplementationClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#implementationClientCapabilities" name="implementationClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ImplementationClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `ImplementationRegistrationOptions`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports additional metadata in the form of definition links.
-	 *
-	 * @since 3.14.0
-	 */
-	linkSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `implementationProvider`
-* property type: `boolean | ImplementationOptions | ImplementationRegistrationOptions` where `ImplementationOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#implementationOptions" name="implementationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ImplementationOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `ImplementationRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#implementationRegistrationOptions" name="implementationRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ImplementationRegistrationOptions extends
-	TextDocumentRegistrationOptions, ImplementationOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/implementation`
-* params: `ImplementationParams` defined as follows:
-
-<div class="anchorHolder"><a href="#implementationParams" name="implementationParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ImplementationParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationLink)[] \| `null`
-* partial result: [`Location`](#location)[] \| [`LocationLink`](#locationLink)[]
-* error: code and message set in case an exception happens during the definition request.
-
-#### <a href="#textDocument_references" name="textDocument_references" class="anchor">Find References Request (:leftwards_arrow_with_hook:)</a>
-
-The references request is sent from the client to the server to resolve project-wide references for the symbol denoted by the given text document position.
-
-_Client Capability_:
-* property name (optional): `textDocument.references`
-* property type: `ReferenceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#referenceClientCapabilities" name="referenceClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ReferenceClientCapabilities {
-	/**
-	 * Whether references supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `referencesProvider`
-* property type: `boolean | ReferenceOptions` where `ReferenceOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#referenceOptions" name="referenceOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ReferenceOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `ReferenceRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#referenceRegistrationOptions" name="referenceRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ReferenceRegistrationOptions extends
-	TextDocumentRegistrationOptions, ReferenceOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/references`
-* params: `ReferenceParams` defined as follows:
-
-<div class="anchorHolder"><a href="#referenceParams" name="referenceParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ReferenceParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-	context: ReferenceContext;
-}
-```
-
-<div class="anchorHolder"><a href="#referenceContext" name="referenceContext" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ReferenceContext {
-	/**
-	 * Include the declaration of the current symbol.
-	 */
-	includeDeclaration: boolean;
-}
-```
-_Response_:
-* result: [`Location`](#location)[] \| `null`
-* partial result: [`Location`](#location)[]
-* error: code and message set in case an exception happens during the reference request.
-
-#### <a href="#textDocument_prepareCallHierarchy" name="textDocument_prepareCallHierarchy" class="anchor">Prepare Call Hierarchy Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The call hierarchy request is sent from the client to the server to return a call hierarchy for the language element of given text document positions. The call hierarchy requests are executed in two steps:
-
-  1. first a call hierarchy item is resolved for the given text document position
-  1. for a call hierarchy item the incoming or outgoing call hierarchy items are resolved.
-
-_Client Capability_:
-
-* property name (optional): `textDocument.callHierarchy`
-* property type: `CallHierarchyClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyClientCapabilities" name="callHierarchyClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-interface CallHierarchyClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
-	 * StaticRegistrationOptions)` return value for the corresponding server
-	 * capability as well.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-
-* property name (optional): `callHierarchyProvider`
-* property type: `boolean | CallHierarchyOptions | CallHierarchyRegistrationOptions` where `CallHierarchyOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyOptions" name="callHierarchyOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `CallHierarchyRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyRegistrationOptions" name="callHierarchyRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyRegistrationOptions extends
-	TextDocumentRegistrationOptions, CallHierarchyOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/prepareCallHierarchy`
-* params: `CallHierarchyPrepareParams` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyPrepareParams" name="callHierarchyPrepareParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyPrepareParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-}
-```
-
-_Response_:
-
-* result: `CallHierarchyItem[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyItem" name="callHierarchyItem" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyItem {
-	/**
-	 * The name of this item.
-	 */
-	name: string;
-
-	/**
-	 * The kind of this item.
-	 */
-	kind: SymbolKind;
-
-	/**
-	 * Tags for this item.
-	 */
-	tags?: SymbolTag[];
-
-	/**
-	 * More detail for this item, e.g. the signature of a function.
-	 */
-	detail?: string;
-
-	/**
-	 * The resource identifier of this item.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The range enclosing this symbol not including leading/trailing whitespace
-	 * but everything else, e.g. comments and code.
-	 */
-	range: Range;
-
-	/**
-	 * The range that should be selected and revealed when this symbol is being
-	 * picked, e.g. the name of a function. Must be contained by the
-	 * [`range`](#CallHierarchyItem.range).
-	 */
-	selectionRange: Range;
-
-	/**
-	 * A data entry field that is preserved between a call hierarchy prepare and
-	 * incoming calls or outgoing calls requests.
-	 */
-	data?: unknown;
-}
-```
-
-* error: code and message set in case an exception happens during the 'textDocument/prepareCallHierarchy' request
-
-#### <a href="#callHierarchy_incomingCalls" name="callHierarchy_incomingCalls" class="anchor">Call Hierarchy Incoming Calls (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The request is sent from the client to the server to resolve incoming calls for a given call hierarchy item. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareCallHierarchy` request](#textDocument_prepareCallHierarchy).
-
-_Request_:
-
-* method: `callHierarchy/incomingCalls`
-* params: `CallHierarchyIncomingCallsParams` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyIncomingCallsParams" name="callHierarchyIncomingCallsParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyIncomingCallsParams extends
-	WorkDoneProgressParams, PartialResultParams {
-	item: CallHierarchyItem;
-}
-```
-
-_Response_:
-
-* result: `CallHierarchyIncomingCall[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyIncomingCall" name="callHierarchyIncomingCall" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyIncomingCall {
-
-	/**
-	 * The item that makes the call.
-	 */
-	from: CallHierarchyItem;
-
-	/**
-	 * The ranges at which the calls appear. This is relative to the caller
-	 * denoted by [`this.from`](#CallHierarchyIncomingCall.from).
-	 */
-	fromRanges: Range[];
-}
-```
-
-* partial result: `CallHierarchyIncomingCall[]`
-* error: code and message set in case an exception happens during the 'callHierarchy/incomingCalls' request
-
-#### <a href="#callHierarchy_outgoingCalls" name="callHierarchy_outgoingCalls" class="anchor">Call Hierarchy Outgoing Calls (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The request is sent from the client to the server to resolve outgoing calls for a given call hierarchy item. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareCallHierarchy` request](#textDocument_prepareCallHierarchy).
-
-_Request_:
-
-* method: `callHierarchy/outgoingCalls`
-* params: `CallHierarchyOutgoingCallsParams` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyOutgoingCallsParams" name="callHierarchyOutgoingCallsParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyOutgoingCallsParams extends
-	WorkDoneProgressParams, PartialResultParams {
-	item: CallHierarchyItem;
-}
-```
-
-_Response_:
-
-* result: `CallHierarchyOutgoingCall[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#callHierarchyOutgoingCall" name="callHierarchyOutgoingCall" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CallHierarchyOutgoingCall {
-
-	/**
-	 * The item that is called.
-	 */
-	to: CallHierarchyItem;
-
-	/**
-	 * The range at which this item is called. This is the range relative to
-	 * the caller, e.g the item passed to `callHierarchy/outgoingCalls` request.
-	 */
-	fromRanges: Range[];
-}
-```
-
-* partial result: `CallHierarchyOutgoingCall[]`
-* error: code and message set in case an exception happens during the 'callHierarchy/outgoingCalls' request
-
-
-#### <a href="#textDocument_prepareTypeHierarchy" name="textDocument_prepareTypeHierarchy" class="anchor">Prepare Type Hierarchy Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The type hierarchy request is sent from the client to the server to return a type hierarchy for the language element of given text document positions. Will return `null` if the server couldn't infer a valid type from the position. The type hierarchy requests are executed in two steps:
-
-  1. first a type hierarchy item is prepared for the given text document position.
-  1. for a type hierarchy item the supertype or subtype type hierarchy items are resolved.
-
-_Client Capability_:
-
-* property name (optional): `textDocument.typeHierarchy`
-* property type: `TypeHierarchyClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchyClientCapabilities" name="typeHierarchyClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchyClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
-	 * StaticRegistrationOptions)` return value for the corresponding server
-	 * capability as well.
-	 */
-	dynamicRegistration?: boolean;
-};
-```
-
-_Server Capability_:
-
-* property name (optional): `typeHierarchyProvider`
-* property type: `boolean | TypeHierarchyOptions | TypeHierarchyRegistrationOptions` where `TypeHierarchyOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchyOptions" name="typeHierarchyOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchyOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `TypeHierarchyRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchyRegistrationOptions" name="typeHierarchyRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchyRegistrationOptions extends
-	TextDocumentRegistrationOptions, TypeHierarchyOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-
-* method: 'textDocument/prepareTypeHierarchy'
-* params: `TypeHierarchyPrepareParams` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchyPrepareParams" name="typeHierarchyPrepareParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchyPrepareParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-}
-```
-
-_Response_:
-
-* result: `TypeHierarchyItem[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchyItem" name="typeHierarchyItem" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchyItem {
-	/**
-	 * The name of this item.
-	 */
-	name: string;
-
-	/**
-	 * The kind of this item.
-	 */
-	kind: SymbolKind;
-
-	/**
-	 * Tags for this item.
-	 */
-	tags?: SymbolTag[];
-
-	/**
-	 * More detail for this item, e.g. the signature of a function.
-	 */
-	detail?: string;
-
-	/**
-	 * The resource identifier of this item.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The range enclosing this symbol not including leading/trailing whitespace
-	 * but everything else, e.g. comments and code.
-	 */
-	range: Range;
-
-	/**
-	 * The range that should be selected and revealed when this symbol is being
-	 * picked, e.g. the name of a function. Must be contained by the
-	 * [`range`](#TypeHierarchyItem.range).
-	 */
-	selectionRange: Range;
-
-	/**
-	 * A data entry field that is preserved between a type hierarchy prepare and
-	 * 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.
-	 */
-	data?: LSPAny;
-}
-```
-
-* error: code and message set in case an exception happens during the 'textDocument/prepareTypeHierarchy' request
-
-#### <a href="#typeHierarchy_supertypes" name="typeHierarchy_supertypes" class="anchor">Type Hierarchy Supertypes(:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The request is sent from the client to the server to resolve the supertypes for a given type hierarchy item. Will return `null` if the server couldn't infer a valid type from `item` in the params. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareTypeHierarchy` request](#textDocument_prepareTypeHierarchy).
-
-_Request_:
-
-* method: 'typeHierarchy/supertypes'
-* params: `TypeHierarchySupertypesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchySupertypesParams" name="typeHierarchySupertypesParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchySupertypesParams extends
-	WorkDoneProgressParams, PartialResultParams {
-	item: TypeHierarchyItem;
-}
-```
-_Response_:
-
-* result: `TypeHierarchyItem[] | null`
-* partial result: `TypeHierarchyItem[]`
-* error: code and message set in case an exception happens during the 'typeHierarchy/supertypes' request
-
-#### <a href="#typeHierarchy_subtypes" name="typeHierarchy_subtypes" class="anchor">Type Hierarchy Subtypes(:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The request is sent from the client to the server to resolve the subtypes for a given type hierarchy item. Will return `null` if the server couldn't infer a valid type from `item` in the params. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareTypeHierarchy` request](#textDocument_prepareTypeHierarchy).
-
-_Request_:
-
-* method: 'typeHierarchy/subtypes'
-* params: `TypeHierarchySubtypesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#typeHierarchySubtypesParams" name="typeHierarchySubtypesParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface TypeHierarchySubtypesParams extends
-	WorkDoneProgressParams, PartialResultParams {
-	item: TypeHierarchyItem;
-}
-```
-_Response_:
-
-* result: `TypeHierarchyItem[] | null`
-* partial result: `TypeHierarchyItem[]`
-* error: code and message set in case an exception happens during the 'typeHierarchy/subtypes' request
-#### <a href="#textDocument_documentHighlight" name="textDocument_documentHighlight" class="anchor">Document Highlights Request (:leftwards_arrow_with_hook:)</a>
-
-The document highlight request is sent from the client to the server to resolve a document highlights for a given text document position.
-For programming languages this usually highlights all references to the symbol scoped to this file. However we kept 'textDocument/documentHighlight'
-and 'textDocument/references' separate requests since the first one is allowed to be more fuzzy. Symbol matches usually have a `DocumentHighlightKind`
-of `Read` or `Write` whereas fuzzy or textual matches use `Text`as the kind.
-
-_Client Capability_:
-* property name (optional): `textDocument.documentHighlight`
-* property type: `DocumentHighlightClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentHighlightClientCapabilities" name="documentHighlightClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentHighlightClientCapabilities {
-	/**
-	 * Whether document highlight supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentHighlightProvider`
-* property type: `boolean | DocumentHighlightOptions` where `DocumentHighlightOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#documentHighlightOptions" name="documentHighlightOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentHighlightOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DocumentHighlightRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentHighlightRegistrationOptions" name="documentHighlightRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentHighlightRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentHighlightOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/documentHighlight`
-* params: `DocumentHighlightParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentHighlightParams" name="documentHighlightParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentHighlightParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-* result: `DocumentHighlight[]` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#documentHighlight" name="documentHighlight" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A document highlight is a range inside a text document which deserves
- * special attention. Usually a document highlight is visualized by changing
- * the background color of its range.
- *
- */
-export interface DocumentHighlight {
-	/**
-	 * The range this highlight applies to.
-	 */
-	range: Range;
-
-	/**
-	 * The highlight kind, default is DocumentHighlightKind.Text.
-	 */
-	kind?: DocumentHighlightKind;
-}
-```
-
-<div class="anchorHolder"><a href="#documentHighlightKind" name="documentHighlightKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A document highlight kind.
- */
-export namespace DocumentHighlightKind {
-	/**
-	 * A textual occurrence.
-	 */
-	export const Text = 1;
-
-	/**
-	 * Read-access of a symbol, like reading a variable.
-	 */
-	export const Read = 2;
-
-	/**
-	 * Write-access of a symbol, like writing to a variable.
-	 */
-	export const Write = 3;
-}
-
-export type DocumentHighlightKind = 1 | 2 | 3;
-```
-
-* partial result: `DocumentHighlight[]`
-* error: code and message set in case an exception happens during the document highlight request.
-
-#### <a href="#textDocument_documentLink" name="textDocument_documentLink" class="anchor">Document Link Request (:leftwards_arrow_with_hook:)</a>
-
-The document links request is sent from the client to the server to request the location of links in a document.
-
-_Client Capability_:
-* property name (optional): `textDocument.documentLink`
-* property type: `DocumentLinkClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentLinkClientCapabilities" name="documentLinkClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentLinkClientCapabilities {
-	/**
-	 * Whether document link supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Whether the client supports the `tooltip` property on `DocumentLink`.
-	 *
-	 * @since 3.15.0
-	 */
-	tooltipSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentLinkProvider`
-* property type: `DocumentLinkOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentLinkOptions" name="documentLinkOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentLinkOptions extends WorkDoneProgressOptions {
-	/**
-	 * Document links have a resolve provider as well.
-	 */
-	resolveProvider?: boolean;
-}
-```
-
-_Registration Options_: `DocumentLinkRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentLinkRegistrationOptions" name="documentLinkRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentLinkRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentLinkOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/documentLink`
-* params: `DocumentLinkParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentLinkParams" name="documentLinkParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DocumentLinkParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The document to provide document links for.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-* result: `DocumentLink[]` \| `null`.
-
-<div class="anchorHolder"><a href="#documentLink" name="documentLink" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A document link is a range in a text document that links to an internal or
- * external resource, like another text document or a web site.
- */
-interface DocumentLink {
-	/**
-	 * The range this link applies to.
-	 */
-	range: Range;
-
-	/**
-	 * The uri this link points to. If missing a resolve request is sent later.
-	 */
-	target?: DocumentUri;
-
-	/**
-	 * The tooltip text when you hover over this link.
-	 *
-	 * If a tooltip is provided, is will be displayed in a string that includes
-	 * instructions on how to trigger the link, such as `{0} (ctrl + click)`.
-	 * The specific instructions vary depending on OS, user settings, and
-	 * localization.
-	 *
-	 * @since 3.15.0
-	 */
-	tooltip?: string;
-
-	/**
-	 * A data entry field that is preserved on a document link between a
-	 * DocumentLinkRequest and a DocumentLinkResolveRequest.
-	 */
-	data?: LSPAny;
-}
-```
-* partial result: `DocumentLink[]`
-* error: code and message set in case an exception happens during the document link request.
-
-#### <a href="#documentLink_resolve" name="documentLink_resolve" class="anchor">Document Link Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-The document link resolve request is sent from the client to the server to resolve the target of a given document link.
-
-_Request_:
-* method: `documentLink/resolve`
-* params: `DocumentLink`
-
-_Response_:
-* result: `DocumentLink`
-* error: code and message set in case an exception happens during the document link resolve request.
-
-#### <a href="#textDocument_hover" name="textDocument_hover" class="anchor">Hover Request (:leftwards_arrow_with_hook:)</a>
-
-The hover request is sent from the client to the server to request hover information at a given text document position.
-
-_Client Capability_:
-* property name (optional): `textDocument.hover`
-* property type: `HoverClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#hoverClientCapabilities" name="hoverClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface HoverClientCapabilities {
-	/**
-	 * Whether hover supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Client supports the follow content formats if the content
-	 * property refers to a `literal of type MarkupContent`.
-	 * The order describes the preferred format of the client.
-	 */
-	contentFormat?: MarkupKind[];
-}
-```
-
-_Server Capability_:
-* property name (optional): `hoverProvider`
-* property type: `boolean | HoverOptions` where `HoverOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#hoverOptions" name="hoverOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface HoverOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `HoverRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#hoverRegistrationOptions" name="hoverRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface HoverRegistrationOptions
-	extends TextDocumentRegistrationOptions, HoverOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/hover`
-* params: `HoverParams` defined as follows:
-
-<div class="anchorHolder"><a href="#hoverParams" name="hoverParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface HoverParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-}
-```
-
-_Response_:
-* result: `Hover` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#hover" name="hover" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The result of a hover request.
- */
-export interface Hover {
-	/**
-	 * The hover's content
-	 */
-	contents: MarkedString | MarkedString[] | MarkupContent;
-
-	/**
-	 * An optional range is a range inside a text document
-	 * that is used to visualize a hover, e.g. by changing the background color.
-	 */
-	range?: Range;
-}
-```
-
-Where `MarkedString` is defined as follows:
-
-<div class="anchorHolder"><a href="#markedString" name="markedString" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * MarkedString can be used to render human readable text. It is either a
- * markdown string or a code-block that provides a language and a code snippet.
- * The language identifier is semantically equal to the optional language
- * identifier in fenced code blocks in GitHub issues.
- *
- * The pair of a language and a value is an equivalent to markdown:
- * ```${language}
- * ${value}
- * ```
- *
- * Note that markdown strings will be sanitized - that means html will be
- * escaped.
- *
- * @deprecated use MarkupContent instead.
- */
-type MarkedString = string | { language: string; value: string };
-```
-
-* error: code and message set in case an exception happens during the hover request.
-
-#### <a href="#textDocument_codeLens" name="textDocument_codeLens" class="anchor">Code Lens Request (:leftwards_arrow_with_hook:)</a>
-
-The code lens request is sent from the client to the server to compute code lenses for a given text document.
-
-_Client Capability_:
-* property name (optional): `textDocument.codeLens`
-* property type: `CodeLensClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLensClientCapabilities" name="codeLensClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeLensClientCapabilities {
-	/**
-	 * Whether code lens supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `codeLensProvider`
-* property type: `CodeLensOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLensOptions" name="codeLensOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeLensOptions extends WorkDoneProgressOptions {
-	/**
-	 * Code lens has a resolve provider as well.
-	 */
-	resolveProvider?: boolean;
-}
-```
-
-_Registration Options_: `CodeLensRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLensRegistrationOptions" name="codeLensRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeLensRegistrationOptions extends
-	TextDocumentRegistrationOptions, CodeLensOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/codeLens`
-* params: `CodeLensParams` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLensParams" name="codeLensParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface CodeLensParams extends WorkDoneProgressParams, PartialResultParams {
-	/**
-	 * The document to request code lens for.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-* result: `CodeLens[]` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLens" name="codeLens" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A code lens represents a command that should be shown along with
- * source text, like the number of references, a way to run tests, etc.
- *
- * A code lens is _unresolved_ when no command is associated to it. For
- * performance reasons the creation of a code lens and resolving should be done
- * in two stages.
- */
-interface CodeLens {
-	/**
-	 * The range in which this code lens is valid. Should only span a single
-	 * line.
-	 */
-	range: Range;
-
-	/**
-	 * The command this code lens represents.
-	 */
-	command?: Command;
-
-	/**
-	 * A data entry field that is preserved on a code lens item between
-	 * a code lens and a code lens resolve request.
-	 */
-	data?: LSPAny;
-}
-```
-* partial result: `CodeLens[]`
-* error: code and message set in case an exception happens during the code lens request.
-
-#### <a href="#codeLens_resolve" name="codeLens_resolve" class="anchor">Code Lens Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-The code lens resolve request is sent from the client to the server to resolve the command for a given code lens item.
-
-_Request_:
-* method: `codeLens/resolve`
-* params: `CodeLens`
-
-_Response_:
-* result: `CodeLens`
-* error: code and message set in case an exception happens during the code lens resolve request.
-
-#### <a href="#codeLens_refresh" name="codeLens_refresh" class="anchor">Code Lens Refresh Request (:arrow_right_hook:)</a>
-
-> *Since version 3.16.0*
-
-The `workspace/codeLens/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the code lenses currently shown in editors. As a result the client should ask the server to recompute the code lenses for these editors. This is useful if a server detects a configuration change which requires a re-calculation of all code lenses. Note that the client still has the freedom to delay the re-calculation of the code lenses if for example an editor is currently not visible.
-
-_Client Capability_:
-
-* property name (optional): `workspace.codeLens`
-* property type: `CodeLensWorkspaceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#codeLensWorkspaceClientCapabilities" name="codeLensWorkspaceClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeLensWorkspaceClientCapabilities {
-	/**
-	 * Whether the client implementation supports a refresh request sent from the
-	 * server to the client.
-	 *
-	 * Note that this event is global and will force the client to refresh all
-	 * code lenses currently shown. It should be used with absolute care and is
-	 * useful for situation where a server for example detect a project wide
-	 * change that requires such a calculation.
-	 */
-	refreshSupport?: boolean;
-}
-```
-
-_Request_:
-
-* method: `workspace/codeLens/refresh`
-* params: none
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'workspace/codeLens/refresh' request
-
-#### <a href="#textDocument_foldingRange" name="textDocument_foldingRange" class="anchor">Folding Range Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.10.0*
-
-The folding range request is sent from the client to the server to return all folding ranges found in a given text document.
-
-_Client Capability_:
-* property name (optional): `textDocument.foldingRange`
-* property type: `FoldingRangeClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#foldingRangeClientCapabilities" name="foldingRangeClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface FoldingRangeClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration for folding range
-	 * providers. If this is set to `true` the client supports the new
-	 * `FoldingRangeRegistrationOptions` return value for the corresponding
-	 * server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The maximum number of folding ranges that the client prefers to receive
-	 * per document. The value serves as a hint, servers are free to follow the
-	 * limit.
-	 */
-	rangeLimit?: uinteger;
-
-	/**
-	 * If set, the client signals that it only supports folding complete lines.
-	 * If set, client will ignore specified `startCharacter` and `endCharacter`
-	 * properties in a FoldingRange.
-	 */
-	lineFoldingOnly?: boolean;
-
-	/**
-	 * Specific options for the folding range kind.
-	 *
-	 * @since 3.17.0
-	 */
-	foldingRangeKind? : {
-		/**
-		 * The folding range kind values the client supports. When this
-		 * property exists the client also guarantees that it will
-		 * handle values outside its set gracefully and falls back
-		 * to a default value when unknown.
-		 */
-		valueSet?: FoldingRangeKind[];
-	};
-
-	/**
-	 * Specific options for the folding range.
-	 * @since 3.17.0
-	 */
-	foldingRange?: {
-		/**
-		* If set, the client signals that it supports setting collapsedText on
-		* folding ranges to display custom labels instead of the default text.
-		*
-		* @since 3.17.0
-		*/
-		collapsedText?: boolean;
-	};
-}
-```
-
-_Server Capability_:
-* property name (optional): `foldingRangeProvider`
-* property type: `boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions` where `FoldingRangeOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#foldingRangeOptions" name="foldingRangeOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface FoldingRangeOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `FoldingRangeRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#foldingRangeRegistrationOptions" name="foldingRangeRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface FoldingRangeRegistrationOptions extends
-	TextDocumentRegistrationOptions, FoldingRangeOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/foldingRange`
-* params: `FoldingRangeParams` defined as follows
-
-<div class="anchorHolder"><a href="#foldingRangeParams" name="foldingRangeParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface FoldingRangeParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-* result: `FoldingRange[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#foldingRangeKind" name="foldingRangeKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A set of predefined range kinds.
- */
-export namespace FoldingRangeKind {
-	/**
-	 * Folding range for a comment
-	 */
-	export const Comment = 'comment';
-
-	/**
-	 * Folding range for a imports or includes
-	 */
-	export const Imports = 'imports';
-
-	/**
-	 * Folding range for a region (e.g. `#region`)
-	 */
-	export const Region = 'region';
-}
-
-/**
- * The type is a string since the value set is extensible
- */
-export type FoldingRangeKind = string;
-```
-
-<div class="anchorHolder"><a href="#foldingRange" name="foldingRange" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents a folding range. To be valid, start and end line must be bigger
- * than zero and smaller than the number of lines in the document. Clients
- * are free to ignore invalid ranges.
- */
-export interface FoldingRange {
-
-	/**
-	 * The zero-based start line of the range to fold. The folded area starts
-	 * after the line's last character. To be valid, the end must be zero or
-	 * larger and smaller than the number of lines in the document.
-	 */
-	startLine: uinteger;
-
-	/**
-	 * The zero-based character offset from where the folded range starts. If
-	 * not defined, defaults to the length of the start line.
-	 */
-	startCharacter?: uinteger;
-
-	/**
-	 * The zero-based end line of the range to fold. The folded area ends with
-	 * the line's last character. To be valid, the end must be zero or larger
-	 * and smaller than the number of lines in the document.
-	 */
-	endLine: uinteger;
-
-	/**
-	 * The zero-based character offset before the folded range ends. If not
-	 * defined, defaults to the length of the end line.
-	 */
-	endCharacter?: uinteger;
-
-	/**
-	 * Describes the kind of the folding range such as `comment` or `region`.
-	 * The kind is used to categorize folding ranges and used by commands like
-	 * 'Fold all comments'. See [FoldingRangeKind](#FoldingRangeKind) for an
-	 * enumeration of standardized kinds.
-	 */
-	kind?: FoldingRangeKind;
-
-	/**
-	 * The text that the client should show when the specified range is
-	 * collapsed. If not defined or not supported by the client, a default
-	 * will be chosen by the client.
-	 *
-	 * @since 3.17.0 - proposed
-	 */
-	collapsedText?: string;
-}
-```
-
-* partial result: `FoldingRange[]`
-* error: code and message set in case an exception happens during the 'textDocument/foldingRange' request
-
-#### <a href="#textDocument_selectionRange" name="textDocument_selectionRange" class="anchor">Selection Range Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.15.0*
-
-The selection range request is sent from the client to the server to return suggested selection ranges at an array of given positions. A selection range is a range around the cursor position which the user might be interested in selecting.
-
-A selection range in the return array is for the position in the provided parameters at the same index. Therefore positions[i] must be contained in result[i].range. To allow for results where some positions have selection ranges and others do not, result[i].range is allowed to be the empty range at positions[i].
-
-Typically, but not necessary, selection ranges correspond to the nodes of the syntax tree.
-
-_Client Capability_:
-* property name (optional): `textDocument.selectionRange`
-* property type: `SelectionRangeClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#selectionRangeClientCapabilities" name="selectionRangeClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SelectionRangeClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration for selection range
-	 * providers. If this is set to `true` the client supports the new
-	 * `SelectionRangeRegistrationOptions` return value for the corresponding
-	 * server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `selectionRangeProvider`
-* property type: `boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions` where `SelectionRangeOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#selectionRangeOptions" name="selectionRangeOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SelectionRangeOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `SelectionRangeRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#selectionRangeRegistrationOptions" name="selectionRangeRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SelectionRangeRegistrationOptions extends
-	SelectionRangeOptions, TextDocumentRegistrationOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/selectionRange`
-* params: `SelectionRangeParams` defined as follows:
-
-<div class="anchorHolder"><a href="#selectionRangeParams" name="selectionRangeParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SelectionRangeParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The positions inside the text document.
-	 */
-	positions: Position[];
-}
-```
-
-_Response_:
-
-* result: `SelectionRange[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#selectionRange" name="selectionRange" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SelectionRange {
-	/**
-	 * The [range](#Range) of this selection range.
-	 */
-	range: Range;
-	/**
-	 * The parent selection range containing this range. Therefore
-	 * `parent.range` must contain `this.range`.
-	 */
-	parent?: SelectionRange;
-}
-```
-
-* partial result: `SelectionRange[]`
-* error: code and message set in case an exception happens during the 'textDocument/selectionRange' request
-
-#### <a href="#textDocument_documentSymbol" name="textDocument_documentSymbol" class="anchor">Document Symbols Request (:leftwards_arrow_with_hook:)</a>
-
-The document symbol request is sent from the client to the server. The returned result is either
-
-- `SymbolInformation[]` which is a flat list of all symbols found in a given text document. Then neither the symbol's location range nor the symbol's container name should be used to infer a hierarchy.
-- `DocumentSymbol[]` which is a hierarchy of symbols found in a given text document.
-
-Servers should whenever possible return `DocumentSymbol` since it is the richer data structure.
-
-_Client Capability_:
-* property name (optional): `textDocument.documentSymbol`
-* property type: `DocumentSymbolClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentSymbolClientCapabilities" name="documentSymbolClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentSymbolClientCapabilities {
-	/**
-	 * Whether document symbol supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Specific capabilities for the `SymbolKind` in the
-	 * `textDocument/documentSymbol` request.
-	 */
-	symbolKind?: {
-		/**
-		 * The symbol kind values the client supports. When this
-		 * property exists the client also guarantees that it will
-		 * handle values outside its set gracefully and falls back
-		 * to a default value when unknown.
-		 *
-		 * If this property is not present the client only supports
-		 * the symbol kinds from `File` to `Array` as defined in
-		 * the initial version of the protocol.
-		 */
-		valueSet?: SymbolKind[];
-	};
-
-	/**
-	 * The client supports hierarchical document symbols.
-	 */
-	hierarchicalDocumentSymbolSupport?: boolean;
-
-	/**
-	 * The client supports tags on `SymbolInformation`. Tags are supported on
-	 * `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
-	 * Clients supporting tags have to handle unknown tags gracefully.
-	 *
-	 * @since 3.16.0
-	 */
-	tagSupport?: {
-		/**
-		 * The tags supported by the client.
-		 */
-		valueSet: SymbolTag[];
-	};
-
-	/**
-	 * The client supports an additional label presented in the UI when
-	 * registering a document symbol provider.
-	 *
-	 * @since 3.16.0
-	 */
-	labelSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentSymbolProvider`
-* property type: `boolean | DocumentSymbolOptions` where `DocumentSymbolOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#documentSymbolOptions" name="documentSymbolOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentSymbolOptions extends WorkDoneProgressOptions {
-	/**
-	 * A human-readable string that is shown when multiple outlines trees
-	 * are shown for the same document.
-	 *
-	 * @since 3.16.0
-	 */
-	label?: string;
-}
-```
-
-_Registration Options_: `DocumentSymbolRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentSymbolRegistrationOptions" name="documentSymbolRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentSymbolRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentSymbolOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/documentSymbol`
-* params: `DocumentSymbolParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentSymbolParams" name="documentSymbolParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentSymbolParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-* result: `DocumentSymbol[]` \| `SymbolInformation[]` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#symbolKind" name="symbolKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A symbol kind.
- */
-export namespace SymbolKind {
-	export const File = 1;
-	export const Module = 2;
-	export const Namespace = 3;
-	export const Package = 4;
-	export const Class = 5;
-	export const Method = 6;
-	export const Property = 7;
-	export const Field = 8;
-	export const Constructor = 9;
-	export const Enum = 10;
-	export const Interface = 11;
-	export const Function = 12;
-	export const Variable = 13;
-	export const Constant = 14;
-	export const String = 15;
-	export const Number = 16;
-	export const Boolean = 17;
-	export const Array = 18;
-	export const Object = 19;
-	export const Key = 20;
-	export const Null = 21;
-	export const EnumMember = 22;
-	export const Struct = 23;
-	export const Event = 24;
-	export const Operator = 25;
-	export const TypeParameter = 26;
-}
-```
-
-<div class="anchorHolder"><a href="#symbolTag" name="symbolTag" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Symbol tags are extra annotations that tweak the rendering of a symbol.
- *
- * @since 3.16
- */
-export namespace SymbolTag {
-
-	/**
-	 * Render a symbol as obsolete, usually using a strike-out.
-	 */
-	export const Deprecated: 1 = 1;
-}
-
-export type SymbolTag = 1;
-```
-
-<div class="anchorHolder"><a href="#documentSymbol" name="documentSymbol" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents programming constructs like variables, classes, interfaces etc.
- * that appear in a document. Document symbols can be hierarchical and they
- * have two ranges: one that encloses its definition and one that points to its
- * most interesting range, e.g. the range of an identifier.
- */
-export interface DocumentSymbol {
-
-	/**
-	 * The name of this symbol. Will be displayed in the user interface and
-	 * therefore must not be an empty string or a string only consisting of
-	 * white spaces.
-	 */
-	name: string;
-
-	/**
-	 * More detail for this symbol, e.g the signature of a function.
-	 */
-	detail?: string;
-
-	/**
-	 * The kind of this symbol.
-	 */
-	kind: SymbolKind;
-
-	/**
-	 * Tags for this document symbol.
-	 *
-	 * @since 3.16.0
-	 */
-	tags?: SymbolTag[];
-
-	/**
-	 * Indicates if this symbol is deprecated.
-	 *
-	 * @deprecated Use tags instead
-	 */
-	deprecated?: boolean;
-
-	/**
-	 * The range enclosing this symbol not including leading/trailing whitespace
-	 * but everything else like comments. This information is typically used to
-	 * determine if the clients cursor is inside the symbol to reveal in the
-	 * symbol in the UI.
-	 */
-	range: Range;
-
-	/**
-	 * The range that should be selected and revealed when this symbol is being
-	 * picked, e.g. the name of a function. Must be contained by the `range`.
-	 */
-	selectionRange: Range;
-
-	/**
-	 * Children of this symbol, e.g. properties of a class.
-	 */
-	children?: DocumentSymbol[];
-}
-```
-
-<div class="anchorHolder"><a href="#symbolInformation" name="symbolInformation" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents information about programming constructs like variables, classes,
- * interfaces etc.
- *
- * @deprecated use DocumentSymbol or WorkspaceSymbol instead.
- */
-export interface SymbolInformation {
-	/**
-	 * The name of this symbol.
-	 */
-	name: string;
-
-	/**
-	 * The kind of this symbol.
-	 */
-	kind: SymbolKind;
-
-	/**
-	 * Tags for this symbol.
-	 *
-	 * @since 3.16.0
-	 */
-	tags?: SymbolTag[];
-
-	/**
-	 * Indicates if this symbol is deprecated.
-	 *
-	 * @deprecated Use tags instead
-	 */
-	deprecated?: boolean;
-
-	/**
-	 * The location of this symbol. The location's range is used by a tool
-	 * to reveal the location in the editor. If the symbol is selected in the
-	 * tool the range's start information is used to position the cursor. So
-	 * the range usually spans more then the actual symbol's name and does
-	 * normally include things like visibility modifiers.
-	 *
-	 * The range doesn't have to denote a node range in the sense of a abstract
-	 * syntax tree. It can therefore not be used to re-construct a hierarchy of
-	 * the symbols.
-	 */
-	location: Location;
-
-	/**
-	 * The name of the symbol containing this symbol. This information is for
-	 * user interface purposes (e.g. to render a qualifier in the user interface
-	 * if necessary). It can't be used to re-infer a hierarchy for the document
-	 * symbols.
-	 */
-	containerName?: string;
-}
-```
-
-* partial result: `DocumentSymbol[]` \| `SymbolInformation[]`. `DocumentSymbol[]` and `SymbolInformation[]` can not be mixed. That means the first chunk defines the type of all the other chunks.
-* error: code and message set in case an exception happens during the document symbol request.
-
-#### <a href="#textDocument_semanticTokens" name="textDocument_semanticTokens" class="anchor">Semantic Tokens (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The request is sent from the client to the server to resolve semantic tokens for a given file. Semantic tokens are used to add additional color information to a file that depends on language specific symbol information. A semantic token request usually produces a large result. The protocol therefore supports encoding tokens with numbers. In addition optional support for deltas is available.
-
-_General Concepts_
-
-Tokens are represented using one token type combined with n token modifiers. A token type is something like `class` or `function` and token modifiers are like `static` or `async`. The protocol defines a set of token types and modifiers but clients are allowed to extend these and announce the values they support in the corresponding client capability. The predefined values are:
-
-<div class="anchorHolder"><a href="#semanticTokenTypes" name="semanticTokenTypes" class="linkableAnchor"></a></div>
-
-```typescript
-export enum SemanticTokenTypes {
-	namespace = 'namespace',
-	/**
-	 * Represents a generic type. Acts as a fallback for types which
-	 * can't be mapped to a specific type like class or enum.
-	 */
-	type = 'type',
-	class = 'class',
-	enum = 'enum',
-	interface = 'interface',
-	struct = 'struct',
-	typeParameter = 'typeParameter',
-	parameter = 'parameter',
-	variable = 'variable',
-	property = 'property',
-	enumMember = 'enumMember',
-	event = 'event',
-	function = 'function',
-	method = 'method',
-	macro = 'macro',
-	keyword = 'keyword',
-	modifier = 'modifier',
-	comment = 'comment',
-	string = 'string',
-	number = 'number',
-	regexp = 'regexp',
-	operator = 'operator'
-	/**
-	 * @since 3.17.0
-	 */
-	decorator = 'decorator'
-}
-```
-
-<div class="anchorHolder"><a href="#semanticTokenModifiers" name="semanticTokenModifiers" class="linkableAnchor"></a></div>
-
-```typescript
-export enum SemanticTokenModifiers {
-	declaration = 'declaration',
-	definition = 'definition',
-	readonly = 'readonly',
-	static = 'static',
-	deprecated = 'deprecated',
-	abstract = 'abstract',
-	async = 'async',
-	modification = 'modification',
-	documentation = 'documentation',
-	defaultLibrary = 'defaultLibrary'
-}
-```
-
-The protocol defines an additional token format capability to allow future extensions of the format. The only format that is currently specified is `relative` expressing that the tokens are described using relative positions (see Integer Encoding for Tokens below).
-
-<div class="anchorHolder"><a href="#tokenFormat" name="tokenFormat" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace TokenFormat {
-	export const Relative: 'relative' = 'relative';
-}
-
-export type TokenFormat = 'relative';
-```
-
-_Integer Encoding for Tokens_
-
-On the capability level types and modifiers are defined using strings. However the real encoding happens using numbers. The server therefore needs to let the client know which numbers it is using for which types and modifiers. They do so using a legend, which is defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensLegend" name="semanticTokensLegend" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensLegend {
-	/**
-	 * The token types a server uses.
-	 */
-	tokenTypes: string[];
-
-	/**
-	 * The token modifiers a server uses.
-	 */
-	tokenModifiers: string[];
-}
-```
-
-Token types are looked up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Since a token type can have n modifiers, multiple token modifiers can be set by using bit flags,
-so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because bits 0 and 1 are set.
-
-There are different ways how the position of a token can be expressed in a file. Absolute positions or relative positions. The protocol for the token format `relative` uses relative positions, because most tokens remain stable relative to each other when edits are made in a file. This simplifies the computation of a delta if a server supports it. So each token is represented using 5 integers. A specific token `i` in the file consists of the following array indices:
-
-- at index `5*i`   - `deltaLine`: token line number, relative to the previous token
-- at index `5*i+1` - `deltaStart`: token start character, relative to the previous token (relative to 0 or the previous token's start if they are on the same line)
-- at index `5*i+2` - `length`: the length of the token.
-- at index `5*i+3` - `tokenType`: will be looked up in `SemanticTokensLegend.tokenTypes`. We currently ask that `tokenType` < 65536.
-- at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
-
-Whether a token can span multiple lines is defined by the client capability `multilineTokenSupport`. If multiline tokens are not supported and a tokens length takes it past the end of the line, it should be treated as if the token ends at the end of the line and will not wrap onto the next line.
-
-The client capability `overlappingTokenSupport` defines whether tokens can overlap each other.
-
-Lets look at a concrete example which uses single line tokens without overlaps for encoding a file with 3 tokens in a number array. We start with absolute positions to demonstrate how they can easily be transformed into relative positions:
-
-```typescript
-{ line: 2, startChar:  5, length: 3, tokenType: "property",
-	tokenModifiers: ["private", "static"]
-},
-{ line: 2, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] },
-{ line: 5, startChar:  2, length: 7, tokenType: "class", tokenModifiers: [] }
-```
-
-First of all, a legend must be devised. This legend must be provided up-front on registration and capture all possible token types and modifiers. For the example we use this legend:
-
-```typescript
-{
-   tokenTypes: ['property', 'type', 'class'],
-   tokenModifiers: ['private', 'static']
-}
-```
-
-The first transformation step is to encode `tokenType` and `tokenModifiers` as integers using the legend. As said, token types are looked up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Multiple token modifiers can be set by using bit flags, so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because bits 0 and 1 are set. Using this legend, the tokens now are:
-
-```typescript
-{ line: 2, startChar:  5, length: 3, tokenType: 0, tokenModifiers: 3 },
-{ line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 },
-{ line: 5, startChar:  2, length: 7, tokenType: 2, tokenModifiers: 0 }
-```
-
-The next step is to represent each token relative to the previous token in the file. In this case, the second token is on the same line as the first token, so the `startChar` of the second token is made relative to the `startChar` of the first token, so it will be `10 - 5`. The third token is on a different line than the second token, so the `startChar` of the third token will not be altered:
-
-```typescript
-{ deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },
-{ deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 },
-{ deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }
-```
-
-Finally, the last step is to inline each of the 5 fields for a token in a single array, which is a memory friendly representation:
-
-```typescript
-// 1st token,  2nd token,  3rd token
-[  2,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0 ]
-```
-
-Now assume that the user types a new empty line at the beginning of the file which results in the following tokens in the file:
-
-```typescript
-{ line: 3, startChar:  5, length: 3, tokenType: "property",
-	tokenModifiers: ["private", "static"]
-},
-{ line: 3, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] },
-{ line: 6, startChar:  2, length: 7, tokenType: "class", tokenModifiers: [] }
-```
-
-Running the same transformations as above will result in the following number array:
-
-```typescript
-// 1st token,  2nd token,  3rd token
-[  3,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0]
-```
-
-The delta is now expressed on these number arrays without any form of interpretation what these numbers mean. This is comparable to the text document edits send from the server to the client to modify the content of a file. Those are character based and don't make any assumption about the meaning of the characters. So `[  2,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0 ]` can be transformed into `[  3,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0]` using the following edit description: `{ start:  0, deleteCount: 1, data: [3] }` which tells the client to simply replace the first number (e.g. `2`) in the array with `3`.
-
-Semantic token edits behave conceptually like [text edits](#textEditArray) on documents: if an edit description consists of n edits all n edits are based on the same state Sm of the number array. They will move the number array from state Sm to Sm+1. A client applying the edits must not assume that they are sorted. An easy algorithm to apply them to the number array is to sort the edits and apply them from the back to the front of the number array.
-
-_Client Capability_:
-
-The following client capabilities are defined for semantic token requests sent from the client to the server:
-
-* property name (optional): `textDocument.semanticTokens`
-* property type: `SemanticTokensClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensClientCapabilities" name="semanticTokensClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-interface SemanticTokensClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
-	 * StaticRegistrationOptions)` return value for the corresponding server
-	 * capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Which requests the client supports and might send to the server
-	 * depending on the server's capability. Please note that clients might not
-	 * show semantic tokens or degrade some of the user experience if a range
-	 * or full request is advertised by the client but not provided by the
-	 * server. If for example the client capability `requests.full` and
-	 * `request.range` are both set to true but the server only provides a
-	 * range provider the client might not render a minimap correctly or might
-	 * even decide to not show any semantic tokens at all.
-	 */
-	requests: {
-		/**
-		 * The client will send the `textDocument/semanticTokens/range` request
-		 * if the server provides a corresponding handler.
-		 */
-		range?: boolean | {
-		};
-
-		/**
-		 * The client will send the `textDocument/semanticTokens/full` request
-		 * if the server provides a corresponding handler.
-		 */
-		full?: boolean | {
-			/**
-			 * The client will send the `textDocument/semanticTokens/full/delta`
-			 * request if the server provides a corresponding handler.
-			 */
-			delta?: boolean;
-		};
-	};
-
-	/**
-	 * The token types that the client supports.
-	 */
-	tokenTypes: string[];
-
-	/**
-	 * The token modifiers that the client supports.
-	 */
-	tokenModifiers: string[];
-
-	/**
-	 * The formats the clients supports.
-	 */
-	formats: TokenFormat[];
-
-	/**
-	 * Whether the client supports tokens that can overlap each other.
-	 */
-	overlappingTokenSupport?: boolean;
-
-	/**
-	 * Whether the client supports tokens that can span multiple lines.
-	 */
-	multilineTokenSupport?: boolean;
-
-	/**
-	 * Whether the client allows the server to actively cancel a
-	 * semantic token request, e.g. supports returning
-	 * ErrorCodes.ServerCancelled. If a server does the client
-	 * needs to retrigger the request.
-	 *
-	 * @since 3.17.0
-	 */
-	serverCancelSupport?: boolean;
-
-	/**
-	 * Whether the client uses semantic tokens to augment existing
-	 * syntax tokens. If set to `true` client side created syntax
-	 * tokens and semantic tokens are both used for colorization. If
-	 * set to `false` the client only uses the returned semantic tokens
-	 * for colorization.
-	 *
-	 * If the value is `undefined` then the client behavior is not
-	 * specified.
-	 *
-	 * @since 3.17.0
-	 */
-	augmentsSyntaxTokens?: boolean;
-}
-```
-
-_Server Capability_:
-
-The following server capabilities are defined for semantic tokens:
-
-* property name (optional): `semanticTokensProvider`
-* property type: `SemanticTokensOptions | SemanticTokensRegistrationOptions` where `SemanticTokensOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensOptions" name="semanticTokensOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensOptions extends WorkDoneProgressOptions {
-	/**
-	 * The legend used by the server
-	 */
-	legend: SemanticTokensLegend;
-
-	/**
-	 * Server supports providing semantic tokens for a specific range
-	 * of a document.
-	 */
-	range?: boolean | {
-	};
-
-	/**
-	 * Server supports providing semantic tokens for a full document.
-	 */
-	full?: boolean | {
-		/**
-		 * The server supports deltas for full documents.
-		 */
-		delta?: boolean;
-	};
-}
-```
-
-_Registration Options_: `SemanticTokensRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensRegistrationOptions" name="semanticTokensRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensRegistrationOptions extends
-	TextDocumentRegistrationOptions, SemanticTokensOptions,
-	StaticRegistrationOptions {
-}
-```
-
-Since the registration option handles range, full and delta requests the method used to register for semantic tokens requests is `textDocument/semanticTokens` and not one of the specific methods described below.
-
-**Requesting semantic tokens for a whole file**
-
-_Request_:
-
-<div class="anchorHolder"><a href="#semanticTokens_fullRequest" name="semanticTokens_fullRequest" class="linkableAnchor"></a></div>
-
-* method: `textDocument/semanticTokens/full`
-* params: `SemanticTokensParams` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensParams" name="semanticTokensParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-
-* result: `SemanticTokens | null` where `SemanticTokens` is defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokens" name="semanticTokens" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokens {
-	/**
-	 * An optional result id. If provided and clients support delta updating
-	 * the client will include the result id in the next semantic token request.
-	 * A server can then instead of computing all semantic tokens again simply
-	 * send a delta.
-	 */
-	resultId?: string;
-
-	/**
-	 * The actual tokens.
-	 */
-	data: uinteger[];
-}
-```
-
-* partial result: `SemanticTokensPartialResult` defines as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensPartialResult" name="semanticTokensPartialResult" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensPartialResult {
-	data: uinteger[];
-}
-```
-
-* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/full' request
-
-**Requesting semantic token delta for a whole file**
-
-_Request_:
-
-<div class="anchorHolder"><a href="#semanticTokens_deltaRequest" name="semanticTokens_deltaRequest" class="linkableAnchor"></a></div>
-
-* method: `textDocument/semanticTokens/full/delta`
-* params: `SemanticTokensDeltaParams` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensDeltaParams" name="semanticTokensDeltaParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensDeltaParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * 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.
-	 */
-	previousResultId: string;
-}
-```
-
-_Response_:
-
-* result: `SemanticTokens | SemanticTokensDelta | null` where `SemanticTokensDelta` is defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensDelta" name="semanticTokensDelta" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensDelta {
-	readonly resultId?: string;
-	/**
-	 * The semantic token edits to transform a previous result into a new
-	 * result.
-	 */
-	edits: SemanticTokensEdit[];
-}
-```
-
-<div class="anchorHolder"><a href="#semanticTokensEdit" name="semanticTokensEdit" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensEdit {
-	/**
-	 * The start offset of the edit.
-	 */
-	start: uinteger;
-
-	/**
-	 * The count of elements to remove.
-	 */
-	deleteCount: uinteger;
-
-	/**
-	 * The elements to insert.
-	 */
-	data?: uinteger[];
-}
-```
-
-* partial result: `SemanticTokensDeltaPartialResult` defines as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensDeltaPartialResult" name="semanticTokensDeltaPartialResult" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensDeltaPartialResult {
-	edits: SemanticTokensEdit[];
-}
-```
-
-* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/full/delta' request
-
-**Requesting semantic tokens for a range**
-
-There are two uses cases where it can be beneficial to only compute semantic tokens for a visible range:
-
-- for faster rendering of the tokens in the user interface when a user opens a file. In this use cases servers should also implement the `textDocument/semanticTokens/full` request as well to allow for flicker free scrolling and semantic coloring of a minimap.
-- if computing semantic tokens for a full document is too expensive servers can only provide a range call. In this case the client might not render a minimap correctly or might even decide to not show any semantic tokens at all.
-
-A server is allowed to compute the semantic tokens for a broader range than requested by the client. However if the server does the semantic tokens for the broader range must be complete and correct.
-
-_Request_:
-
-<div class="anchorHolder"><a href="#semanticTokens_rangeRequest" name="semanticTokens_rangeRequest" class="linkableAnchor"></a></div>
-
-* method: `textDocument/semanticTokens/range`
-* params: `SemanticTokensRangeParams` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensRangeParams" name="semanticTokensRangeParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensRangeParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The range the semantic tokens are requested for.
-	 */
-	range: Range;
-}
-```
-
-_Response_:
-
-* result: `SemanticTokens | null`
-* partial result: `SemanticTokensPartialResult`
-* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/range' request
-
-**Requesting a refresh of all semantic tokens**
-
-The `workspace/semanticTokens/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the editors for which this server provides semantic tokens. As a result the client should ask the server to recompute the semantic tokens for these editors. This is useful if a server detects a project wide configuration change which requires a re-calculation of all semantic tokens. Note that the client still has the freedom to delay the re-calculation of the semantic tokens if for example an editor is currently not visible.
-
-_Client Capability_:
-
-* property name (optional): `workspace.semanticTokens`
-* property type: `SemanticTokensWorkspaceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#semanticTokensWorkspaceClientCapabilities" name="semanticTokensWorkspaceClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SemanticTokensWorkspaceClientCapabilities {
-	/**
-	 * Whether the client implementation supports a refresh request sent from
-	 * the server to the client.
-	 *
-	 * Note that this event is global and will force the client to refresh all
-	 * semantic tokens currently shown. It should be used with absolute care
-	 * and is useful for situation where a server for example detect a project
-	 * wide change that requires such a calculation.
-	 */
-	refreshSupport?: boolean;
-}
-```
-
-_Request_:
-
-<div class="anchorHolder"><a href="#semanticTokens_refreshRequest" name="semanticTokens_refreshRequest" class="linkableAnchor"></a></div>
-
-* method: `workspace/semanticTokens/refresh`
-* params: none
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'workspace/semanticTokens/refresh' request
-
-#### <a href="#textDocument_inlayHint" name="textDocument_inlayHint" class="anchor">Inlay Hint Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The inlay hints request is sent from the client to the server to compute inlay hints for a given [text document, range] tuple that may be rendered in the editor in place with other text.
-
-_Client Capability_:
-* property name (optional): `textDocument.inlayHint`
-* property type: `InlayHintClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHintClientCapabilities" name="inlayHintClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inlay hint client capabilities.
- *
- * @since 3.17.0
- */
-export interface InlayHintClientCapabilities {
-
-	/**
-	 * Whether inlay hints support dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Indicates which properties a client can resolve lazily on a inlay
-	 * hint.
-	 */
-	resolveSupport?: {
-
-		/**
-		 * The properties that a client can resolve lazily.
-		 */
-		properties: string[];
-	};
-}
-```
-
-_Server Capability_:
-* property name (optional): `inlayHintProvider`
-* property type: `InlayHintOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHintOptions" name="inlayHintOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inlay hint options used during static registration.
- *
- * @since 3.17.0
- */
-export interface InlayHintOptions extends WorkDoneProgressOptions {
-	/**
-	 * The server provides support to resolve additional
-	 * information for an inlay hint item.
-	 */
-	resolveProvider?: boolean;
-}
-```
-
-_Registration Options_: `InlayHintRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHintRegistrationOptions" name="inlayHintRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inlay hint options used during static or dynamic registration.
- *
- * @since 3.17.0
- */
-export interface InlayHintRegistrationOptions extends InlayHintOptions,
-	TextDocumentRegistrationOptions, StaticRegistrationOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/inlayHint`
-* params: `InlayHintParams` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHintParams" name="inlayHintParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A parameter literal used in inlay hint requests.
- *
- * @since 3.17.0
- */
-export interface InlayHintParams extends WorkDoneProgressParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The visible document range for which inlay hints should be computed.
-	 */
-	range: Range;
-}
-```
-
-_Response_:
-* result: `InlayHint[]` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHint" name="inlayHint" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inlay hint information.
- *
- * @since 3.17.0
- */
-export interface InlayHint {
-
-	/**
-	 * The position of this hint.
-	 */
-	position: Position;
-
-	/**
-	 * The label of this hint. A human readable string or an array of
-	 * InlayHintLabelPart label parts.
-	 *
-	 * *Note* that neither the string nor the label part can be empty.
-	 */
-	label: string | InlayHintLabelPart[];
-
-	/**
-	 * The kind of this hint. Can be omitted in which case the client
-	 * should fall back to a reasonable default.
-	 */
-	kind?: InlayHintKind;
-
-	/**
-	 * Optional text edits that are performed when accepting this inlay hint.
-	 *
-	 * *Note* that edits are expected to change the document so that the inlay
-	 * hint (or its nearest variant) is now part of the document and the inlay
-	 * hint itself is now obsolete.
-	 *
-	 * Depending on the client capability `inlayHint.resolveSupport` clients
-	 * might resolve this property late using the resolve request.
-	 */
-	textEdits?: TextEdit[];
-
-	/**
-	 * The tooltip text when you hover over this item.
-	 *
-	 * Depending on the client capability `inlayHint.resolveSupport` clients
-	 * might resolve this property late using the resolve request.
-	 */
-	tooltip?: string | MarkupContent;
-
-	/**
-	 * Render padding before the hint.
-	 *
-	 * Note: Padding should use the editor's background color, not the
-	 * background color of the hint itself. That means padding can be used
-	 * to visually align/separate an inlay hint.
-	 */
-	paddingLeft?: boolean;
-
-	/**
-	 * Render padding after the hint.
-	 *
-	 * Note: Padding should use the editor's background color, not the
-	 * background color of the hint itself. That means padding can be used
-	 * to visually align/separate an inlay hint.
-	 */
-	paddingRight?: boolean;
-
-
-	/**
-	 * A data entry field that is preserved on a inlay hint between
-	 * a `textDocument/inlayHint` and a `inlayHint/resolve` request.
-	 */
-	data?: LSPAny;
-}
-```
-
-<div class="anchorHolder"><a href="#inlayHintLabelPart" name="inlayHintLabelPart" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * An inlay hint label part allows for interactive and composite labels
- * of inlay hints.
- *
- * @since 3.17.0
- */
-export interface InlayHintLabelPart {
-
-	/**
-	 * The value of this label part.
-	 */
-	value: string;
-
-	/**
-	 * The tooltip text when you hover over this label part. Depending on
-	 * the client capability `inlayHint.resolveSupport` clients might resolve
-	 * this property late using the resolve request.
-	 */
-	tooltip?: string | MarkupContent;
-
-	/**
-	 * An optional source code location that represents this
-	 * label part.
-	 *
-	 * The editor will use this location for the hover and for code navigation
-	 * features: This part will become a clickable link that resolves to the
-	 * definition of the symbol at the given location (not necessarily the
-	 * location itself), it shows the hover that shows at the given location,
-	 * and it shows a context menu with further code navigation commands.
-	 *
-	 * Depending on the client capability `inlayHint.resolveSupport` clients
-	 * might resolve this property late using the resolve request.
-	 */
-	location?: Location;
-
-	/**
-	 * An optional command for this label part.
-	 *
-	 * Depending on the client capability `inlayHint.resolveSupport` clients
-	 * might resolve this property late using the resolve request.
-	 */
-	command?: Command;
-}
-```
-
-<div class="anchorHolder"><a href="#inlayHintKind" name="inlayHintKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inlay hint kinds.
- *
- * @since 3.17.0
- */
-export namespace InlayHintKind {
-
-	/**
-	 * An inlay hint that for a type annotation.
-	 */
-	export const Type = 1;
-
-	/**
-	 * An inlay hint that is for a parameter.
-	 */
-	export const Parameter = 2;
-};
-```
-
-* error: code and message set in case an exception happens during the inlay hint request.
-
-#### <a href="#inlayHint_resolve" name="inlayHint_resolve" class="anchor">Inlay Hint Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The request is sent from the client to the server to resolve additional information for a given inlay hint. This is usually used to compute
-the `tooltip`, `location` or `command` properties of a inlay hint's label part to avoid its unnecessary computation during the `textDocument/inlayHint` request.
-
-Consider the clients announces the `label.location` property as a property that can be resolved lazy using the client capability
-
-```typescript
-textDocument.inlayHint.resolveSupport = { properties: ['label.location'] };
-```
-
-then an inlay hint with a label part without a location needs to be resolved using the `inlayHint/resolve` request before it can be used.
-
-_Client Capability_:
-* property name (optional): `textDocument.inlayHint.resolveSupport`
-* property type: `{ properties: string[]; }`
-
-_Request_:
-* method: `inlayHint/resolve`
-* params: `InlayHint`
-
-_Response_:
-* result: `InlayHint`
-* error: code and message set in case an exception happens during the completion resolve request.
-
-#### <a href="#workspace_inlayHint_refresh" name="workspace_inlayHint_refresh" class="anchor">Inlay Hint Refresh Request  (:arrow_right_hook:)</a>
-
-> *Since version 3.17.0*
-
-The `workspace/inlayHint/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the inlay hints currently shown in editors. As a result the client should ask the server to recompute the inlay hints for these editors. This is useful if a server detects a configuration change which requires a re-calculation of all inlay hints. Note that the client still has the freedom to delay the re-calculation of the inlay hints if for example an editor is currently not visible.
-
-_Client Capability_:
-
-* property name (optional): `workspace.inlayHint`
-* property type: `InlayHintWorkspaceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#inlayHintWorkspaceClientCapabilities" name="inlayHintWorkspaceClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Client workspace capabilities specific to inlay hints.
- *
- * @since 3.17.0
- */
-export interface InlayHintWorkspaceClientCapabilities {
-	/**
-	 * Whether the client implementation supports a refresh request sent from
-	 * the server to the client.
-	 *
-	 * Note that this event is global and will force the client to refresh all
-	 * inlay hints currently shown. It should be used with absolute care and
-	 * is useful for situation where a server for example detects a project wide
-	 * change that requires such a calculation.
-	 */
-	refreshSupport?: boolean;
-}
-```
-
-_Request_:
-* method: `workspace/inlayHint/refresh`
-* params: none
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'workspace/inlayHint/refresh' request
-
-#### <a href="#textDocument_inlineValue" name="textDocument_inlineValue" class="anchor">Inline Value Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.17.0*
-
-The inline value request is sent from the client to the server to compute inline values for a given text document that may be rendered in the editor at the end of lines.
-
-_Client Capability_:
-* property name (optional): `textDocument.inlineValue`
-* property type: `InlineValueClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueClientCapabilities" name="inlineValueClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Client capabilities specific to inline values.
- *
- * @since 3.17.0
- */
-export interface InlineValueClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration for inline
-	 * value providers.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `inlineValueProvider`
-* property type: `InlineValueOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueOptions" name="inlineValueOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inline value options used during static registration.
- *
- * @since 3.17.0
- */
-export interface InlineValueOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `InlineValueRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueRegistrationOptions" name="inlineValueRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Inline value options used during static or dynamic registration.
- *
- * @since 3.17.0
- */
-export interface InlineValueRegistrationOptions extends InlineValueOptions,
-	TextDocumentRegistrationOptions, StaticRegistrationOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/inlineValue`
-* params: `InlineValueParams` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueParams" name="inlineValueParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A parameter literal used in inline value requests.
- *
- * @since 3.17.0
- */
-export interface InlineValueParams extends WorkDoneProgressParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The document range for which inline values should be computed.
-	 */
-	range: Range;
-
-	/**
-	 * Additional information about the context in which inline values were
-	 * requested.
-	 */
-	context: InlineValueContext;
-}
-```
-
-<div class="anchorHolder"><a href="#inlineValueContext" name="inlineValueContext" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * @since 3.17.0
- */
-export interface InlineValueContext {
-	/**
-	 * The stack frame (as a DAP Id) where the execution has stopped.
-	 */
-	frameId: integer;
-
-	/**
-	 * The document range where execution has stopped.
-	 * Typically the end position of the range denotes the line where the
-	 * inline values are shown.
-	 */
-	stoppedLocation: Range;
-}
-```
-
-_Response_:
-* result: `InlineValue[]` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueText" name="inlineValueText" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Provide inline value as text.
- *
- * @since 3.17.0
- */
-export interface InlineValueText {
-	/**
-	 * The document range for which the inline value applies.
-	 */
-	range: Range;
-
-	/**
-	 * The text of the inline value.
-	 */
-	text: string;
-}
-```
-
-<div class="anchorHolder"><a href="#inlineValueVariableLookup" name="inlineValueVariableLookup" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Provide inline value through a variable lookup.
- *
- * If only a range is specified, the variable name will be extracted from
- * the underlying document.
- *
- * An optional variable name can be used to override the extracted name.
- *
- * @since 3.17.0
- */
-export interface InlineValueVariableLookup {
-	/**
-	 * The document range for which the inline value applies.
-	 * The range is used to extract the variable name from the underlying
-	 * document.
-	 */
-	range: Range;
-
-	/**
-	 * If specified the name of the variable to look up.
-	 */
-	variableName?: string;
-
-	/**
-	 * How to perform the lookup.
-	 */
-	caseSensitiveLookup: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#inlineValueEvaluatableExpression" name="inlineValueEvaluatableExpression" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Provide an inline value through an expression evaluation.
- *
- * If only a range is specified, the expression will be extracted from the
- * underlying document.
- *
- * An optional expression can be used to override the extracted expression.
- *
- * @since 3.17.0
- */
-export interface InlineValueEvaluatableExpression {
-	/**
-	 * The document range for which the inline value applies.
-	 * The range is used to extract the evaluatable expression from the
-	 * underlying document.
-	 */
-	range: Range;
-
-	/**
-	 * If specified the expression overrides the extracted expression.
-	 */
-	expression?: string;
-}
-```
-
-<div class="anchorHolder"><a href="#inlineValue" name="inlineValue" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * 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
- */
-export type InlineValue = InlineValueText | InlineValueVariableLookup
-	| InlineValueEvaluatableExpression;
-```
-* error: code and message set in case an exception happens during the inline values request.
-
-#### <a href="#workspace_inlineValue_refresh" name="workspace_inlineValue_refresh" class="anchor">Inline Value Refresh Request  (:arrow_right_hook:)</a>
-
-> *Since version 3.17.0*
-
-The `workspace/inlineValue/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the inline values currently shown in editors. As a result the client should ask the server to recompute the inline values for these editors. This is useful if a server detects a configuration change which requires a re-calculation of all inline values. Note that the client still has the freedom to delay the re-calculation of the inline values if for example an editor is currently not visible.
-
-_Client Capability_:
-
-* property name (optional): `workspace.inlineValue`
-* property type: `InlineValueWorkspaceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#inlineValueWorkspaceClientCapabilities" name="inlineValueWorkspaceClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Client workspace capabilities specific to inline values.
- *
- * @since 3.17.0
- */
-export interface InlineValueWorkspaceClientCapabilities {
-	/**
-	 * Whether the client implementation supports a refresh request sent from
-	 * the server to the client.
-	 *
-	 * Note that this event is global and will force the client to refresh all
-	 * inline values currently shown. It should be used with absolute care and
-	 * is useful for situation where a server for example detect a project wide
-	 * change that requires such a calculation.
-	 */
-	refreshSupport?: boolean;
-}
-```
-_Request_:
-* method: `workspace/inlineValue/refresh`
-* params: none
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'workspace/inlineValue/refresh' request
-
-#### <a href="#textDocument_moniker" name="textDocument_moniker" class="anchor">Monikers (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-Language Server Index Format (LSIF) introduced the concept of symbol monikers to help associate symbols across different indexes. This request adds capability for LSP server implementations to provide the same symbol moniker information given a text document position. Clients can utilize this method to get the moniker at the current location in a file user is editing and do further code navigation queries in other services that rely on LSIF indexes and link symbols together.
-
-The `textDocument/moniker` request is sent from the client to the server to get the symbol monikers for a given text document position. An array of Moniker types is returned as response to indicate possible monikers at the given location. If no monikers can be calculated, an empty array or `null` should be returned.
-
-_Client Capabilities_:
-
-* property name (optional): `textDocument.moniker`
-* property type: `MonikerClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#monikerClientCapabilities" name="monikerClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-interface MonikerClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
-	 * StaticRegistrationOptions)` return value for the corresponding server
-	 * capability as well.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-
-* property name (optional): `monikerProvider`
-* property type: `boolean | MonikerOptions | MonikerRegistrationOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#monikerOptions" name="monikerOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface MonikerOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `MonikerRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#monikerRegistrationOptions" name="monikerRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface MonikerRegistrationOptions extends
-	TextDocumentRegistrationOptions, MonikerOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/moniker`
-* params: `MonikerParams` defined as follows:
-
-<div class="anchorHolder"><a href="#monikerParams" name="monikerParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface MonikerParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-}
-```
-
-_Response_:
-
-* result: `Moniker[] | null`
-* partial result: `Moniker[]`
-* error: code and message set in case an exception happens during the 'textDocument/moniker' request
-
-`Moniker` is defined as follows:
-
-<div class="anchorHolder"><a href="#uniquenessLevel" name="uniquenessLevel" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Moniker uniqueness level to define scope of the moniker.
- */
-export enum UniquenessLevel {
-	/**
-	 * The moniker is only unique inside a document
-	 */
-	document = 'document',
-
-	/**
-	 * The moniker is unique inside a project for which a dump got created
-	 */
-	project = 'project',
-
-	/**
-	 * The moniker is unique inside the group to which a project belongs
-	 */
-	group = 'group',
-
-	/**
-	 * The moniker is unique inside the moniker scheme.
-	 */
-	scheme = 'scheme',
-
-	/**
-	 * The moniker is globally unique
-	 */
-	global = 'global'
-}
-```
-
-<div class="anchorHolder"><a href="#monikerKind" name="monikerKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The moniker kind.
- */
-export enum MonikerKind {
-	/**
-	 * The moniker represent a symbol that is imported into a project
-	 */
-	import = 'import',
-
-	/**
-	 * The moniker represents a symbol that is exported from a project
-	 */
-	export = 'export',
-
-	/**
-	 * The moniker represents a symbol that is local to a project (e.g. a local
-	 * variable of a function, a class not visible outside the project, ...)
-	 */
-	local = 'local'
-}
-```
-
-<div class="anchorHolder"><a href="#moniker" name="moniker" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Moniker definition to match LSIF 0.5 moniker definition.
- */
-export interface Moniker {
-	/**
-	 * The scheme of the moniker. For example tsc or .Net
-	 */
-	scheme: string;
-
-	/**
-	 * The identifier of the moniker. The value is opaque in LSIF however
-	 * schema owners are allowed to define the structure if they want.
-	 */
-	identifier: string;
-
-	/**
-	 * The scope in which the moniker is unique
-	 */
-	unique: UniquenessLevel;
-
-	/**
-	 * The moniker kind if known.
-	 */
-	kind?: MonikerKind;
-}
-```
-
-##### Notes
-
-Server implementations of this method should ensure that the moniker calculation matches to those used in the corresponding LSIF implementation to ensure symbols can be associated correctly across IDE sessions and LSIF indexes.
-#### <a href="#textDocument_completion" name="textDocument_completion" class="anchor">Completion Request (:leftwards_arrow_with_hook:)</a>
-
-The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) user interface. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the `textDocument/completion` request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. By default the request can only delay the computation of the `detail` and `documentation` properties. Since 3.16.0 the client
-can signal that it can resolve more properties lazily. This is done using the `completionItem#resolveSupport` client capability which lists all properties that can be filled in during a 'completionItem/resolve' request. All other properties (usually `sortText`, `filterText`, `insertText` and `textEdit`) must be provided in the `textDocument/completion` response and must not be changed during resolve.
-
-The language server protocol uses the following model around completions:
-
-- to achieve consistency across languages and to honor different clients usually the client is responsible for filtering and sorting. This has also the advantage that client can experiment with different filter and sorting models. However servers can enforce different behavior by setting a `filterText` / `sortText`
-- for speed clients should be able to filter an already received completion list if the user continues typing. Servers can opt out of this using a `CompletionList` and mark it as `isIncomplete`.
-
-A completion item provides additional means to influence filtering and sorting. They are expressed by either creating a `CompletionItem` with a `insertText` or with a `textEdit`. The two modes differ as follows:
-
-- **Completion item provides an insertText / label without a text edit**: in the model the client should filter against what the user has already typed using the word boundary rules of the language (e.g. resolving the word under the cursor position). The reason for this mode is that it makes it extremely easy for a server to implement a basic completion list and get it filtered on the client.
-
-- **Completion Item with text edits**: in this mode the server tells the client that it actually knows what it is doing. If you create a completion item with a text edit at the current cursor position no word guessing takes place and no filtering should happen. This mode can be combined with a sort text and filter text to customize two things. If the text edit is a replace edit then the range denotes the word used for filtering. If the replace changes the text it most likely makes sense to specify a filter text to be used.
-
-_Client Capability_:
-* property name (optional): `textDocument.completion`
-* property type: `CompletionClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#completionClientCapabilities" name="completionClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CompletionClientCapabilities {
-	/**
-	 * Whether completion supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports the following `CompletionItem` specific
-	 * capabilities.
-	 */
-	completionItem?: {
-		/**
-		 * Client supports snippets as insert text.
-		 *
-		 * A snippet can define tab stops and placeholders with `$1`, `$2`
-		 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
-		 * the end of the snippet. Placeholders with equal identifiers are
-		 * linked, that is typing in one will update others too.
-		 */
-		snippetSupport?: boolean;
-
-		/**
-		 * Client supports commit characters on a completion item.
-		 */
-		commitCharactersSupport?: boolean;
-
-		/**
-		 * Client supports the follow content formats for the documentation
-		 * property. The order describes the preferred format of the client.
-		 */
-		documentationFormat?: MarkupKind[];
-
-		/**
-		 * Client supports the deprecated property on a completion item.
-		 */
-		deprecatedSupport?: boolean;
-
-		/**
-		 * Client supports the preselect property on a completion item.
-		 */
-		preselectSupport?: boolean;
-
-		/**
-		 * Client supports the tag property on a completion item. Clients
-		 * supporting tags have to handle unknown tags gracefully. Clients
-		 * especially need to preserve unknown tags when sending a completion
-		 * item back to the server in a resolve call.
-		 *
-		 * @since 3.15.0
-		 */
-		tagSupport?: {
-			/**
-			 * The tags supported by the client.
-			 */
-			valueSet: CompletionItemTag[];
-		};
-
-		/**
-		 * Client supports insert replace edit to control different behavior if
-		 * a completion item is inserted in the text or should replace text.
-		 *
-		 * @since 3.16.0
-		 */
-		insertReplaceSupport?: boolean;
-
-		/**
-		 * Indicates which properties a client can resolve lazily on a
-		 * completion item. Before version 3.16.0 only the predefined properties
-		 * `documentation` and `detail` could be resolved lazily.
-		 *
-		 * @since 3.16.0
-		 */
-		resolveSupport?: {
-			/**
-			 * The properties that a client can resolve lazily.
-			 */
-			properties: string[];
-		};
-
-		/**
-		 * The client supports the `insertTextMode` property on
-		 * a completion item to override the whitespace handling mode
-		 * as defined by the client (see `insertTextMode`).
-		 *
-		 * @since 3.16.0
-		 */
-		insertTextModeSupport?: {
-			valueSet: InsertTextMode[];
-		};
-
-		/**
-		 * The client has support for completion item label
-		 * details (see also `CompletionItemLabelDetails`).
-		 *
-		 * @since 3.17.0
-		 */
-		labelDetailsSupport?: boolean;
-	};
-
-	completionItemKind?: {
-		/**
-		 * The completion item kind values the client supports. When this
-		 * property exists the client also guarantees that it will
-		 * handle values outside its set gracefully and falls back
-		 * to a default value when unknown.
-		 *
-		 * If this property is not present the client only supports
-		 * the completion items kinds from `Text` to `Reference` as defined in
-		 * the initial version of the protocol.
-		 */
-		valueSet?: CompletionItemKind[];
-	};
-
-	/**
-	 * The client supports to send additional context information for a
-	 * `textDocument/completion` request.
-	 */
-	contextSupport?: boolean;
-
-	/**
-	 * The client's default when the completion item doesn't provide a
-	 * `insertTextMode` property.
-	 *
-	 * @since 3.17.0
-	 */
-	insertTextMode?: InsertTextMode;
-
-	/**
-	 * The client supports the following `CompletionList` specific
-	 * capabilities.
-	 *
-	 * @since 3.17.0
-	 */
-	completionList?: {
-		/**
-		 * The client supports the the following itemDefaults on
-		 * a completion list.
-		 *
-		 * The value lists the supported property names of the
-		 * `CompletionList.itemDefaults` object. If omitted
-		 * no properties are supported.
-		 *
-		 * @since 3.17.0
-		 */
-		itemDefaults?: string[];
-	}
-}
-```
-
-_Server Capability_:
-* property name (optional): `completionProvider`
-* property type: `CompletionOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#completionOptions" name="completionOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Completion options.
- */
-export interface CompletionOptions extends WorkDoneProgressOptions {
-	/**
-	 * Most tools trigger completion request automatically without explicitly
-	 * requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
-	 * do so when the user starts to type an identifier. For example if the user
-	 * types `c` in a JavaScript file code complete will automatically pop up
-	 * present `console` besides others as a completion item. Characters that
-	 * make up identifiers don't need to be listed here.
-	 *
-	 * If code complete should automatically be trigger on characters not being
-	 * valid inside an identifier (for example `.` in JavaScript) list them in
-	 * `triggerCharacters`.
-	 */
-	triggerCharacters?: string[];
-
-	/**
-	 * The list of all possible characters that commit a completion. This field
-	 * can be used if clients don't support individual commit characters per
-	 * completion item. See client capability
-	 * `completion.completionItem.commitCharactersSupport`.
-	 *
-	 * If a server provides both `allCommitCharacters` and commit characters on
-	 * an individual completion item the ones on the completion item win.
-	 *
-	 * @since 3.2.0
-	 */
-	allCommitCharacters?: string[];
-
-	/**
-	 * The server provides support to resolve additional
-	 * information for a completion item.
-	 */
-	resolveProvider?: boolean;
-
-	/**
-	 * The server supports the following `CompletionItem` specific
-	 * capabilities.
-	 *
-	 * @since 3.17.0
-	 */
-	completionItem?: {
-		/**
-		 * The server has support for completion item label
-		 * details (see also `CompletionItemLabelDetails`) when receiving
-		 * a completion item in a resolve call.
-		 *
-		 * @since 3.17.0
-		 */
-		labelDetailsSupport?: boolean;
-	}
-}
-```
-
-_Registration Options_: `CompletionRegistrationOptions` options defined as follows:
-
-<div class="anchorHolder"><a href="#completionRegistrationOptions" name="completionRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CompletionRegistrationOptions
-	extends TextDocumentRegistrationOptions, CompletionOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/completion`
-* params: `CompletionParams` defined as follows:
-
-<div class="anchorHolder"><a href="#completionParams" name="completionParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CompletionParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams, PartialResultParams {
-	/**
-	 * The completion context. This is only available if the client specifies
-	 * to send this using the client capability
-	 * `completion.contextSupport === true`
-	 */
-	context?: CompletionContext;
-}
-```
-
-<div class="anchorHolder"><a href="#completionTriggerKind" name="completionTriggerKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * How a completion was triggered
- */
-export namespace CompletionTriggerKind {
-	/**
-	 * Completion was triggered by typing an identifier (24x7 code
-	 * complete), manual invocation (e.g Ctrl+Space) or via API.
-	 */
-	export const Invoked: 1 = 1;
-
-	/**
-	 * Completion was triggered by a trigger character specified by
-	 * the `triggerCharacters` properties of the
-	 * `CompletionRegistrationOptions`.
-	 */
-	export const TriggerCharacter: 2 = 2;
-
-	/**
-	 * Completion was re-triggered as the current completion list is incomplete.
-	 */
-	export const TriggerForIncompleteCompletions: 3 = 3;
-}
-export type CompletionTriggerKind = 1 | 2 | 3;
-```
-
-<div class="anchorHolder"><a href="#completionContext" name="completionContext" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Contains additional information about the context in which a completion
- * request is triggered.
- */
-export interface CompletionContext {
-	/**
-	 * How the completion was triggered.
-	 */
-	triggerKind: CompletionTriggerKind;
-
-	/**
-	 * The trigger character (a single character) that has trigger code
-	 * complete. Is undefined if
-	 * `triggerKind !== CompletionTriggerKind.TriggerCharacter`
-	 */
-	triggerCharacter?: string;
-}
-```
-
-_Response_:
-* result: `CompletionItem[]` \| `CompletionList` \| `null`. If a `CompletionItem[]` is provided it is interpreted to be complete. So it is the same as `{ isIncomplete: false, items }`
-
-<div class="anchorHolder"><a href="#completionList" name="completionList" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents a collection of [completion items](#CompletionItem) to be
- * presented in the editor.
- */
-export interface CompletionList {
-	/**
-	 * This list is not complete. Further typing should result in recomputing
-	 * this list.
-	 *
-	 * Recomputed lists have all their items replaced (not appended) in the
-	 * incomplete completion sessions.
-	 */
-	isIncomplete: boolean;
-
-	/**
-	 * In many cases the items of an actual completion result share the same
-	 * value for properties like `commitCharacters` or the range of a text
-	 * edit. A completion list can therefore define item defaults which will
-	 * be used if a completion item itself doesn't specify the value.
-	 *
-	 * If a completion list specifies a default value and a completion item
-	 * also specifies a corresponding value the one from the item is used.
-	 *
-	 * Servers are only allowed to return default values if the client
-	 * signals support for this via the `completionList.itemDefaults`
-	 * capability.
-	 *
-	 * @since 3.17.0
-	 */
-	itemDefaults?: {
-		/**
-		 * A default commit character set.
-		 *
-		 * @since 3.17.0
-		 */
-		commitCharacters?: string[];
-
-		/**
-		 * A default edit range
-		 *
-		 * @since 3.17.0
-		 */
-		editRange?: Range | {
-			insert: Range;
-			replace: Range;
-		};
-
-		/**
-		 * A default insert text format
-		 *
-		 * @since 3.17.0
-		 */
-		insertTextFormat?: InsertTextFormat;
-
-		/**
-		 * A default insert text mode
-		 *
-		 * @since 3.17.0
-		 */
-		insertTextMode?: InsertTextMode;
-
-		/**
-		 * A default data value.
-		 *
-		 * @since 3.17.0
-		 */
-		data?: LSPAny;
-	}
-
-	/**
-	 * The completion items.
-	 */
-	items: CompletionItem[];
-}
-```
-
-<div class="anchorHolder"><a href="#insertTextFormat" name="insertTextFormat" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Defines whether the insert text in a completion item should be interpreted as
- * plain text or a snippet.
- */
-export namespace InsertTextFormat {
-	/**
-	 * The primary text to be inserted is treated as a plain string.
-	 */
-	export const PlainText = 1;
-
-	/**
-	 * The primary text to be inserted is treated as a snippet.
-	 *
-	 * A snippet can define tab stops and placeholders with `$1`, `$2`
-	 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
-	 * the end of the snippet. Placeholders with equal identifiers are linked,
-	 * that is typing in one will update others too.
-	 */
-	export const Snippet = 2;
-}
-
-export type InsertTextFormat = 1 | 2;
-```
-
-<div class="anchorHolder"><a href="#completionItemTag" name="completionItemTag" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Completion item tags are extra annotations that tweak the rendering of a
- * completion item.
- *
- * @since 3.15.0
- */
-export namespace CompletionItemTag {
-	/**
-	 * Render a completion as obsolete, usually using a strike-out.
-	 */
-	export const Deprecated = 1;
-}
-
-export type CompletionItemTag = 1;
-```
-
-<div class="anchorHolder"><a href="#insertReplaceEdit" name="insertReplaceEdit" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A special text edit to provide an insert and a replace operation.
- *
- * @since 3.16.0
- */
-export interface InsertReplaceEdit {
-	/**
-	 * The string to be inserted.
-	 */
-	newText: string;
-
-	/**
-	 * The range if the insert is requested
-	 */
-	insert: Range;
-
-	/**
-	 * The range if the replace is requested.
-	 */
-	replace: Range;
-}
-```
-
-<div class="anchorHolder"><a href="#insertTextMode" name="insertTextMode" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * How whitespace and indentation is handled during completion
- * item insertion.
- *
- * @since 3.16.0
- */
-export namespace InsertTextMode {
-	/**
-	 * The insertion or replace strings is taken as it is. If the
-	 * value is multi line the lines below the cursor will be
-	 * inserted using the indentation defined in the string value.
-	 * The client will not apply any kind of adjustments to the
-	 * string.
-	 */
-	export const asIs: 1 = 1;
-
-	/**
-	 * The editor adjusts leading whitespace of new lines so that
-	 * they match the indentation up to the cursor of the line for
-	 * which the item is accepted.
-	 *
-	 * Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a
-	 * multi line completion item is indented using 2 tabs and all
-	 * following lines inserted will be indented using 2 tabs as well.
-	 */
-	export const adjustIndentation: 2 = 2;
-}
-
-export type InsertTextMode = 1 | 2;
-```
-
-<div class="anchorHolder"><a href="#completionItemLabelDetails" name="completionItemLabelDetails" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Additional details for a completion item label.
- *
- * @since 3.17.0
- */
-export interface CompletionItemLabelDetails {
-
-	/**
-	 * An optional string which is rendered less prominently directly after
-	 * {@link CompletionItem.label label}, without any spacing. Should be
-	 * used for function signatures or type annotations.
-	 */
-	detail?: string;
-
-	/**
-	 * An optional string which is rendered less prominently after
-	 * {@link CompletionItemLabelDetails.detail}. Should be used for fully qualified
-	 * names or file path.
-	 */
-	description?: string;
-}
-```
-
-<div class="anchorHolder"><a href="#completionItem" name="completionItem" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CompletionItem {
-
-	/**
-	 * The label of this completion item.
-	 *
-	 * The label property is also by default the text that
-	 * is inserted when selecting this completion.
-	 *
-	 * If label details are provided the label itself should
-	 * be an unqualified name of the completion item.
-	 */
-	label: string;
-
-	/**
-	 * Additional details for the label
-	 *
-	 * @since 3.17.0
-	 */
-	labelDetails?: CompletionItemLabelDetails;
-
-
-	/**
-	 * The kind of this completion item. Based of the kind
-	 * an icon is chosen by the editor. The standardized set
-	 * of available values is defined in `CompletionItemKind`.
-	 */
-	kind?: CompletionItemKind;
-
-	/**
-	 * Tags for this completion item.
-	 *
-	 * @since 3.15.0
-	 */
-	tags?: CompletionItemTag[];
-
-	/**
-	 * A human-readable string with additional information
-	 * about this item, like type or symbol information.
-	 */
-	detail?: string;
-
-	/**
-	 * A human-readable string that represents a doc-comment.
-	 */
-	documentation?: string | MarkupContent;
-
-	/**
-	 * Indicates if this item is deprecated.
-	 *
-	 * @deprecated Use `tags` instead if supported.
-	 */
-	deprecated?: boolean;
-
-	/**
-	 * Select this item when showing.
-	 *
-	 * *Note* that only one completion item can be selected and that the
-	 * tool / client decides which item that is. The rule is that the *first*
-	 * item of those that match best is selected.
-	 */
-	preselect?: boolean;
-
-	/**
-	 * A string that should be used when comparing this item
-	 * with other items. When `falsy` the label is used
-	 * as the sort text for this item.
-	 */
-	sortText?: string;
-
-	/**
-	 * A string that should be used when filtering a set of
-	 * completion items. When `falsy` the label is used as the
-	 * filter text for this item.
-	 */
-	filterText?: string;
-
-	/**
-	 * A string that should be inserted into a document when selecting
-	 * this completion. When `falsy` the label is used as the insert text
-	 * for this item.
-	 *
-	 * The `insertText` is subject to interpretation by the client side.
-	 * Some tools might not take the string literally. For example
-	 * VS Code when code complete is requested in this example
-	 * `con<cursor position>` and a completion item with an `insertText` of
-	 * `console` is provided it will only insert `sole`. Therefore it is
-	 * recommended to use `textEdit` instead since it avoids additional client
-	 * side interpretation.
-	 */
-	insertText?: string;
-
-	/**
-	 * The format of the insert text. The format applies to both the
-	 * `insertText` property and the `newText` property of a provided
-	 * `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
-	 *
-	 * Please note that the insertTextFormat doesn't apply to
-	 * `additionalTextEdits`.
-	 */
-	insertTextFormat?: InsertTextFormat;
-
-	/**
-	 * How whitespace and indentation is handled during completion
-	 * item insertion. If not provided the client's default value depends on
-	 * the `textDocument.completion.insertTextMode` client capability.
-	 *
-	 * @since 3.16.0
-	 * @since 3.17.0 - support for `textDocument.completion.insertTextMode`
-	 */
-	insertTextMode?: InsertTextMode;
-
-	/**
-	 * An edit which is applied to a document when selecting this completion.
-	 * When an edit is provided the value of `insertText` is ignored.
-	 *
-	 * *Note:* The range of the edit must be a single line range and it must
-	 * contain the position at which completion has been requested.
-	 *
-	 * Most editors support two different operations when accepting a completion
-	 * item. One is to insert a completion text and the other is to replace an
-	 * existing text with a completion text. Since this can usually not be
-	 * predetermined by a server it can report both ranges. Clients need to
-	 * signal support for `InsertReplaceEdit`s via the
-	 * `textDocument.completion.completionItem.insertReplaceSupport` client
-	 * capability property.
-	 *
-	 * *Note 1:* The text edit's range as well as both ranges from an insert
-	 * replace edit must be a [single line] and they must contain the position
-	 * at which completion has been requested.
-	 * *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
-	 * must be a prefix of the edit's replace range, that means it must be
-	 * contained and starting at the same position.
-	 *
-	 * @since 3.16.0 additional type `InsertReplaceEdit`
-	 */
-	textEdit?: TextEdit | InsertReplaceEdit;
-
-	/**
-	 * The edit text used if the completion item is part of a CompletionList and
-	 * CompletionList defines an item default for the text edit range.
-	 *
-	 * Clients will only honor this property if they opt into completion list
-	 * item defaults using the capability `completionList.itemDefaults`.
-	 *
-	 * If not provided and a list's default range is provided the label
-	 * property is used as a text.
-	 *
-	 * @since 3.17.0
-	 */
-	textEditText?: string;
-
-	/**
-	 * An optional array of additional text edits that are applied when
-	 * selecting this completion. Edits must not overlap (including the same
-	 * insert position) with the main edit nor with themselves.
-	 *
-	 * Additional text edits should be used to change text unrelated to the
-	 * current cursor position (for example adding an import statement at the
-	 * top of the file if the completion item will insert an unqualified type).
-	 */
-	additionalTextEdits?: TextEdit[];
-
-	/**
-	 * An optional set of characters that when pressed while this completion is
-	 * active will accept it first and then type that character. *Note* that all
-	 * commit characters should have `length=1` and that superfluous characters
-	 * will be ignored.
-	 */
-	commitCharacters?: string[];
-
-	/**
-	 * An optional command that is executed *after* inserting this completion.
-	 * *Note* that additional modifications to the current document should be
-	 * described with the additionalTextEdits-property.
-	 */
-	command?: Command;
-
-	/**
-	 * A data entry field that is preserved on a completion item between
-	 * a completion and a completion resolve request.
-	 */
-	data?: LSPAny;
-}
-```
-
-<div class="anchorHolder"><a href="#completionItemKind" name="completionItemKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The kind of a completion entry.
- */
-export namespace CompletionItemKind {
-	export const Text = 1;
-	export const Method = 2;
-	export const Function = 3;
-	export const Constructor = 4;
-	export const Field = 5;
-	export const Variable = 6;
-	export const Class = 7;
-	export const Interface = 8;
-	export const Module = 9;
-	export const Property = 10;
-	export const Unit = 11;
-	export const Value = 12;
-	export const Enum = 13;
-	export const Keyword = 14;
-	export const Snippet = 15;
-	export const Color = 16;
-	export const File = 17;
-	export const Reference = 18;
-	export const Folder = 19;
-	export const EnumMember = 20;
-	export const Constant = 21;
-	export const Struct = 22;
-	export const Event = 23;
-	export const Operator = 24;
-	export const TypeParameter = 25;
-}
-```
-* partial result: `CompletionItem[]` or `CompletionList` followed by `CompletionItem[]`. If the first provided result item is of type `CompletionList` subsequent partial results of `CompletionItem[]` add to the `items` property of the `CompletionList`.
-* error: code and message set in case an exception happens during the completion request.
-
-Completion items support snippets (see `InsertTextFormat.Snippet`). The snippet format is as follows:
-
-##### <a href="#snippet_syntax" name="snippet_syntax" class="anchor">Snippet Syntax</a>
-
-The `body` of a snippet can use special constructs to control cursors and the text being inserted. The following are supported features and their syntaxes:
-
-##### Tab stops
-
-With tab stops, you can make the editor cursor move inside a snippet. Use `$1`, `$2` to specify cursor locations. The number is the order in which tab stops will be visited, whereas `$0` denotes the final cursor position. Multiple tab stops are linked and updated in sync.
-
-##### Placeholders
-
-Placeholders are tab stops with values, like `${1:foo}`. The placeholder text will be inserted and selected such that it can be easily changed. Placeholders can be nested, like `${1:another ${2:placeholder}}`.
-
-##### Choice
-
-Placeholders can have choices as values. The syntax is a comma separated enumeration of values, enclosed with the pipe-character, for example `${1|one,two,three|}`. When the snippet is inserted and the placeholder selected, choices will prompt the user to pick one of the values.
-
-##### Variables
-
-With `$name` or `${name:default}` you can insert the value of a variable. When a variable isn’t set, its *default* or the empty string is inserted. When a variable is unknown (that is, its name isn’t defined) the name of the variable is inserted and it is transformed into a placeholder.
-
-The following variables can be used:
-
-* `TM_SELECTED_TEXT` The currently selected text or the empty string
-* `TM_CURRENT_LINE` The contents of the current line
-* `TM_CURRENT_WORD` The contents of the word under cursor or the empty string
-* `TM_LINE_INDEX` The zero-index based line number
-* `TM_LINE_NUMBER` The one-index based line number
-* `TM_FILENAME` The filename of the current document
-* `TM_FILENAME_BASE` The filename of the current document without its extensions
-* `TM_DIRECTORY` The directory of the current document
-* `TM_FILEPATH` The full file path of the current document
-
-##### Variable Transforms
-
-Transformations allow you to modify the value of a variable before it is inserted. The definition of a transformation consists of three parts:
-
-1. A [regular expression](#regExp) that is matched against the value of a variable, or the empty string when the variable cannot be resolved.
-2. A "format string" that allows to reference matching groups from the regular expression. The format string allows for conditional inserts and simple modifications.
-3. Options that are passed to the regular expression.
-
-The following example inserts the name of the current file without its ending, so from `foo.txt` it makes `foo`.
-
-```
-${TM_FILENAME/(.*)\..+$/$1/}
-  |           |         | |
-  |           |         | |-> no options
-  |           |         |
-  |           |         |-> references the contents of the first
-  |           |             capture group
-  |           |
-  |           |-> regex to capture everything before
-  |               the final `.suffix`
-  |
-  |-> resolves to the filename
-```
-
-##### Grammar
-
-Below is the EBNF ([extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus-Naur_form)) for snippets. With `\` (backslash), you can escape `$`, `}` and `\`. Within choice elements, the backslash also escapes comma and pipe characters.
-
-```
-any         ::= tabstop | placeholder | choice | variable | text
-tabstop     ::= '$' int | '${' int '}'
-placeholder ::= '${' int ':' any '}'
-choice      ::= '${' int '|' text (',' text)* '|}'
-variable    ::= '$' var | '${' var }'
-                | '${' var ':' any '}'
-                | '${' var '/' regex '/' (format | text)+ '/' options '}'
-format      ::= '$' int | '${' int '}'
-                | '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'
-                | '${' int ':+' if '}'
-                | '${' int ':?' if ':' else '}'
-                | '${' int ':-' else '}' | '${' int ':' else '}'
-regex       ::= Regular Expression value (ctor-string)
-options     ::= Regular Expression option (ctor-options)
-var         ::= [_a-zA-Z] [_a-zA-Z0-9]*
-int         ::= [0-9]+
-text        ::= .*
-```
-
-#### <a href="#completionItem_resolve" name="completionItem_resolve" class="anchor">Completion Item Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-The request is sent from the client to the server to resolve additional information for a given completion item.
-
-_Request_:
-* method: `completionItem/resolve`
-* params: `CompletionItem`
-
-_Response_:
-* result: `CompletionItem`
-* error: code and message set in case an exception happens during the completion resolve request.
-
-#### <a href="#textDocument_publishDiagnostics" name="textDocument_publishDiagnostics" class="anchor">PublishDiagnostics Notification (:arrow_left:)</a>
-
-Diagnostics notification are sent from the server to the client to signal results of validation runs.
-
-Diagnostics are "owned" by the server so it is the server's responsibility to clear them if necessary. The following rule is used for VS Code servers that generate diagnostics:
-
-* if a language is single file only (for example HTML) then diagnostics are cleared by the server when the file is closed. Please note that open / close events don't necessarily reflect what the user sees in the user interface. These events are ownership events. So with the current version of the specification it is possible that problems are not cleared although the file is not visible in the user interface since the client has not closed the file yet.
-* if a language has a project system (for example C#) diagnostics are not cleared when a file closes. When a project is opened all diagnostics for all files are recomputed (or read from a cache).
-
-When a file changes it is the server's responsibility to re-compute diagnostics and push them to the client. If the computed set is empty it has to push the empty array to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. There is no merging that happens on the client side.
-
-See also the [Diagnostic](#diagnostic) section.
-
-_Client Capability_:
-* property name (optional): `textDocument.publishDiagnostics`
-* property type: `PublishDiagnosticsClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#publishDiagnosticsClientCapabilities" name="publishDiagnosticsClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface PublishDiagnosticsClientCapabilities {
-	/**
-	 * Whether the clients accepts diagnostics with related information.
-	 */
-	relatedInformation?: boolean;
-
-	/**
-	 * Client supports the tag property to provide meta data about a diagnostic.
-	 * Clients supporting tags have to handle unknown tags gracefully.
-	 *
-	 * @since 3.15.0
-	 */
-	tagSupport?: {
-		/**
-		 * The tags supported by the client.
-		 */
-		valueSet: DiagnosticTag[];
-	};
-
-	/**
-	 * Whether the client interprets the version property of the
-	 * `textDocument/publishDiagnostics` notification's parameter.
-	 *
-	 * @since 3.15.0
-	 */
-	versionSupport?: boolean;
-
-	/**
-	 * Client supports a codeDescription property
-	 *
-	 * @since 3.16.0
-	 */
-	codeDescriptionSupport?: boolean;
-
-	/**
-	 * Whether code action supports the `data` property which is
-	 * preserved between a `textDocument/publishDiagnostics` and
-	 * `textDocument/codeAction` request.
-	 *
-	 * @since 3.16.0
-	 */
-	dataSupport?: boolean;
-}
-```
-
-_Notification_:
-* method: `textDocument/publishDiagnostics`
-* params: `PublishDiagnosticsParams` defined as follows:
-
-<div class="anchorHolder"><a href="#publishDiagnosticsParams" name="publishDiagnosticsParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface PublishDiagnosticsParams {
-	/**
-	 * The URI for which diagnostic information is reported.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * Optional the version number of the document the diagnostics are published
-	 * for.
-	 *
-	 * @since 3.15.0
-	 */
-	version?: integer;
-
-	/**
-	 * An array of diagnostic information items.
-	 */
-	diagnostics: Diagnostic[];
-}
-```
-
-#### <a href="#textDocument_pullDiagnostics" name="textDocument_pullDiagnostics" class="anchor">Pull Diagnostics</a>
-
-Diagnostics are currently published by the server to the client using a notification. This model has the advantage that for workspace wide diagnostics the server has the freedom to compute them at a server preferred point in time. On the other hand the approach has the disadvantage that the server can't prioritize the computation for the file in which the user types or which are visible in the editor. Inferring the client's UI state from the `textDocument/didOpen` and `textDocument/didChange` notifications might lead to false positives since these notifications are ownership transfer notifications.
-
-The specification therefore introduces the concept of diagnostic pull requests to give a client more control over the documents for which diagnostics should be computed and at which point in time.
-
-_Client Capability_:
-* property name (optional): `textDocument.diagnostic`
-* property type: `DiagnosticClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#diagnosticClientCapabilities" name="diagnosticClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Client capabilities specific to diagnostic pull requests.
- *
- * @since 3.17.0
- */
-export interface DiagnosticClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration. If this is set to
-	 * `true` the client supports the new
-	 * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Whether the clients supports related documents for document diagnostic
-	 * pulls.
-	 */
-	relatedDocumentSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `diagnosticProvider`
-* property type: `DiagnosticOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#diagnosticOptions" name="diagnosticOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Diagnostic options.
- *
- * @since 3.17.0
- */
-export interface DiagnosticOptions extends WorkDoneProgressOptions {
-	/**
-	 * An optional identifier under which the diagnostics are
-	 * managed by the client.
-	 */
-	identifier?: string;
-
-	/**
-	 * Whether the language has inter file dependencies meaning that
-	 * editing code in one file can result in a different diagnostic
-	 * set in another file. Inter file dependencies are common for
-	 * most programming languages and typically uncommon for linters.
-	 */
-	interFileDependencies: boolean;
-
-	/**
-	 * The server provides support for workspace diagnostics as well.
-	 */
-	workspaceDiagnostics: boolean;
-}
-```
-
-_Registration Options_: `DiagnosticRegistrationOptions` options defined as follows:
-
-<div class="anchorHolder"><a href="#diagnosticRegistrationOptions" name="diagnosticRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Diagnostic registration options.
- *
- * @since 3.17.0
- */
-export interface DiagnosticRegistrationOptions extends
-	TextDocumentRegistrationOptions, DiagnosticOptions,
-	StaticRegistrationOptions {
-}
-```
-
-##### <a href="#textDocument_diagnostic" name="textDocument_diagnostic" class="anchor">Document Diagnostics(:leftwards_arrow_with_hook:)</a>
-
-The text document diagnostic request is sent from the client to the server to ask the server to compute the diagnostics for a given document. As with other pull requests the server is asked to compute the diagnostics for the currently synced version of the document.
-
-_Request_:
-* method: 'textDocument/diagnostic'.
-* params: `DocumentDiagnosticParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentDiagnosticParams" name="documentDiagnosticParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Parameters of the document diagnostic request.
- *
- * @since 3.17.0
- */
-export interface DocumentDiagnosticParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The additional identifier  provided during registration.
-	 */
-	identifier?: string;
-
-	/**
-	 * The result id of a previous response if provided.
-	 */
-	previousResultId?: string;
-}
-```
-
-_Response_:
-* result: `DocumentDiagnosticReport` defined as follows:
-
-<div class="anchorHolder"><a href="#documentDiagnosticReport" name="documentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The result of a document diagnostic pull request. A report can
- * either be a full report containing all diagnostics for the
- * requested document or a unchanged report indicating that nothing
- * has changed in terms of diagnostics in comparison to the last
- * pull request.
- *
- * @since 3.17.0
- */
-export type DocumentDiagnosticReport = RelatedFullDocumentDiagnosticReport
-	| RelatedUnchangedDocumentDiagnosticReport;
-```
-
-<div class="anchorHolder"><a href="#documentDiagnosticReportKind" name="documentDiagnosticReportKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The document diagnostic report kinds.
- *
- * @since 3.17.0
- */
-export namespace DocumentDiagnosticReportKind {
-	/**
-	 * A diagnostic report with a full
-	 * set of problems.
-	 */
-	export const Full = 'full';
-
-	/**
-	 * A report indicating that the last
-	 * returned report is still accurate.
-	 */
-	export const Unchanged = 'unchanged';
-}
-
-export type DocumentDiagnosticReportKind = 'full' | 'unchanged';
-```
-
-<div class="anchorHolder"><a href="#fullDocumentDiagnosticReport" name="fullDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A diagnostic report with a full set of problems.
- *
- * @since 3.17.0
- */
-export interface FullDocumentDiagnosticReport {
-	/**
-	 * A full document diagnostic report.
-	 */
-	kind: 'full';
-
-	/**
-	 * An optional result id. If provided it will
-	 * be sent on the next diagnostic request for the
-	 * same document.
-	 */
-	resultId?: string;
-
-	/**
-	 * The actual items.
-	 */
-	items: Diagnostic[];
-}
-```
-
-<div class="anchorHolder"><a href="#unchangedDocumentDiagnosticReport" name="unchangedDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A diagnostic report indicating that the last returned
- * report is still accurate.
- *
- * @since 3.17.0
- */
-export interface UnchangedDocumentDiagnosticReport {
-	/**
-	 * A document diagnostic report indicating
-	 * no changes to the last result. A server can
-	 * only return `unchanged` if result ids are
-	 * provided.
-	 */
-	kind: 'unchanged';
-
-	/**
-	 * A result id which will be sent on the next
-	 * diagnostic request for the same document.
-	 */
-	resultId: string;
-}
-```
-
-<div class="anchorHolder"><a href="#relatedFullDocumentDiagnosticReport" name="relatedFullDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A full diagnostic report with a set of related documents.
- *
- * @since 3.17.0
- */
-export interface RelatedFullDocumentDiagnosticReport extends
-	FullDocumentDiagnosticReport {
-	/**
-	 * Diagnostics of related documents. This information is useful
-	 * in programming languages where code in a file A can generate
-	 * diagnostics in a file B which A depends on. An example of
-	 * such a language is C/C++ where marco definitions in a file
-	 * a.cpp and result in errors in a header file b.hpp.
-	 *
-	 * @since 3.17.0
-	 */
-	relatedDocuments?: {
-		[uri: string /** DocumentUri */]:
-			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
-	};
-}
-```
-
-<div class="anchorHolder"><a href="#relatedUnchangedDocumentDiagnosticReport" name="relatedUnchangedDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * An unchanged diagnostic report with a set of related documents.
- *
- * @since 3.17.0
- */
-export interface RelatedUnchangedDocumentDiagnosticReport extends
-	UnchangedDocumentDiagnosticReport {
-	/**
-	 * Diagnostics of related documents. This information is useful
-	 * in programming languages where code in a file A can generate
-	 * diagnostics in a file B which A depends on. An example of
-	 * such a language is C/C++ where marco definitions in a file
-	 * a.cpp and result in errors in a header file b.hpp.
-	 *
-	 * @since 3.17.0
-	 */
-	relatedDocuments?: {
-		[uri: string /** DocumentUri */]:
-			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
-	};
-}
-```
-* partial result: The first literal send need to be a `DocumentDiagnosticReport` followed by n `DocumentDiagnosticReportPartialResult` literals defined as follows:
-
-<div class="anchorHolder"><a href="#documentDiagnosticReportPartialResult" name="documentDiagnosticReportPartialResult" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A partial result for a document diagnostic report.
- *
- * @since 3.17.0
- */
-export interface DocumentDiagnosticReportPartialResult {
-	relatedDocuments: {
-		[uri: string /** DocumentUri */]:
-			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
-	};
-}
-```
-* error: code and message set in case an exception happens during the diagnostic request. A server is also allowed to return an error with code `ServerCancelled` indicating that the server can't compute the result right now. A server can return a `DiagnosticServerCancellationData` data to indicate whether the client should re-trigger the request. If no data is provided it defaults to `{ retriggerRequest: true }`:
-
-<div class="anchorHolder"><a href="#diagnosticServerCancellationData" name="diagnosticServerCancellationData" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Cancellation data returned from a diagnostic request.
- *
- * @since 3.17.0
- */
-export interface DiagnosticServerCancellationData {
-	retriggerRequest: boolean;
-}
-```
-
-##### <a href="#workspace_diagnostic" name="workspace_diagnostic" class="anchor">Workspace Diagnostics(:leftwards_arrow_with_hook:)</a>
-
-The workspace diagnostic request is sent from the client to the server to ask the server to compute workspace wide diagnostics which previously where pushed from the server to the client. In contrast to the document diagnostic request the workspace request can be long running and is not bound to a specific workspace or document state. If the client supports streaming for the workspace diagnostic pull it is legal to provide a document diagnostic report multiple times for the same document URI. The last one reported will win over previous reports.
-
-If a client receives a diagnostic report for a document in a workspace diagnostic request for which the client also issues individual document diagnostic pull requests the client needs to decide which diagnostics win and should be presented. In general:
-
-- diagnostics for a higher document version should win over those from a lower document version (e.g. note that document versions are steadily increasing)
-- diagnostics from a document pull should win over diagnostics form a workspace pull if no version information is provided.
-
-_Request_:
-* method: 'workspace/diagnostic'.
-* params: `WorkspaceDiagnosticParams` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceDiagnosticParams" name="workspaceDiagnosticParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Parameters of the workspace diagnostic request.
- *
- * @since 3.17.0
- */
-export interface WorkspaceDiagnosticParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The additional identifier provided during registration.
-	 */
-	identifier?: string;
-
-	/**
-	 * The currently known diagnostic reports with their
-	 * previous result ids.
-	 */
-	previousResultIds: PreviousResultId[];
-}
-```
-
-<div class="anchorHolder"><a href="#previousResultId" name="previousResultId" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A previous result id in a workspace pull request.
- *
- * @since 3.17.0
- */
-export interface PreviousResultId {
-	/**
-	 * The URI for which the client knowns a
-	 * result id.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The value of the previous result id.
-	 */
-	value: string;
-}
-```
-
-_Response_:
-* result: `WorkspaceDiagnosticReport` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceDiagnosticReport" name="workspaceDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A workspace diagnostic report.
- *
- * @since 3.17.0
- */
-export interface WorkspaceDiagnosticReport {
-	items: WorkspaceDocumentDiagnosticReport[];
-}
-```
-
-<div class="anchorHolder"><a href="#workspaceFullDocumentDiagnosticReport" name="workspaceFullDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A full document diagnostic report for a workspace diagnostic result.
- *
- * @since 3.17.0
- */
-export interface WorkspaceFullDocumentDiagnosticReport extends
-	FullDocumentDiagnosticReport {
-
-	/**
-	 * The URI for which diagnostic information is reported.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The version number for which the diagnostics are reported.
-	 * If the document is not marked as open `null` can be provided.
-	 */
-	version: integer | null;
-}
-```
-
-<div class="anchorHolder"><a href="#workspaceUnchangedDocumentDiagnosticReport" name="workspaceUnchangedDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * An unchanged document diagnostic report for a workspace diagnostic result.
- *
- * @since 3.17.0
- */
-export interface WorkspaceUnchangedDocumentDiagnosticReport extends
-	UnchangedDocumentDiagnosticReport {
-
-	/**
-	 * The URI for which diagnostic information is reported.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The version number for which the diagnostics are reported.
-	 * If the document is not marked as open `null` can be provided.
-	 */
-	version: integer | null;
-};
-```
-
-<div class="anchorHolder"><a href="#workspaceDocumentDiagnosticReport" name="workspaceDocumentDiagnosticReport" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A workspace diagnostic document report.
- *
- * @since 3.17.0
- */
-export type WorkspaceDocumentDiagnosticReport =
-	WorkspaceFullDocumentDiagnosticReport
-	| WorkspaceUnchangedDocumentDiagnosticReport;
-```
-
-* partial result: The first literal send need to be a `WorkspaceDiagnosticReport` followed by n `DocumentDiagnosticReportPartialResult` literals defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceDiagnosticReportPartialResult" name="workspaceDiagnosticReportPartialResult" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A partial result for a workspace diagnostic report.
- *
- * @since 3.17.0
- */
-export interface WorkspaceDiagnosticReportPartialResult {
-	items: WorkspaceDocumentDiagnosticReport[];
-}
-```
-
-* error: code and message set in case an exception happens during the diagnostic request. A server is also allowed to return and error with code `ServerCancelled` indicating that the server can't compute the result right now. A server can return a `DiagnosticServerCancellationData` data to indicate whether the client should re-trigger the request. If no data is provided it defaults to `{ retriggerRequest: true }`:
-
-##### <a href="#diagnostic_refresh" name="diagnostic_refresh" class="anchor">Diagnostics Refresh(:arrow_right_hook:)</a>
-
-The `workspace/diagnostic/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh all needed document and workspace diagnostics. This is useful if a server detects a project wide configuration change which requires a re-calculation of all diagnostics.
-
-_Client Capability_:
-
-* property name (optional): `workspace.diagnostics`
-* property type: `DiagnosticWorkspaceClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#diagnosticWorkspaceClientCapabilities" name="diagnosticWorkspaceClientCapabilities" class="linkableAnchor"></a></div>
-
-
-```typescript
-/**
- * Workspace client capabilities specific to diagnostic pull requests.
- *
- * @since 3.17.0
- */
-export interface DiagnosticWorkspaceClientCapabilities {
-	/**
-	 * Whether the client implementation supports a refresh request sent from
-	 * the server to the client.
-	 *
-	 * Note that this event is global and will force the client to refresh all
-	 * pulled diagnostics currently shown. It should be used with absolute care
-	 * and is useful for situation where a server for example detects a project
-	 * wide change that requires such a calculation.
-	 */
-	refreshSupport?: boolean;
-}
-```
-
-_Request_:
-* method: `workspace/diagnostic/refresh`
-* params: none
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'workspace/diagnostic/refresh' request
-
-
-##### Implementation Considerations
-
-Generally the language server specification doesn't enforce any specific client implementation since those usually depend on how the client UI behaves. However since diagnostics can be provided on a document and workspace level here are some tips:
-
-- a client should pull actively for the document the users types in.
-- if the server signals inter file dependencies a client should also pull for visible documents to ensure accurate diagnostics. However the pull should happen less frequently.
-- if the server signals workspace pull support a client should also pull for workspace diagnostics. It is recommended for clients to implement partial result progress for the workspace pull to allow servers to keep the request open for a long time. If a server closes a workspace diagnostic pull request the client should re-trigger the request.
-
-#### <a href="#textDocument_signatureHelp" name="textDocument_signatureHelp" class="anchor">Signature Help Request (:leftwards_arrow_with_hook:)</a>
-
-The signature help request is sent from the client to the server to request signature information at a given cursor position.
-
-_Client Capability_:
-* property name (optional): `textDocument.signatureHelp`
-* property type: `SignatureHelpClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#signatureHelpClientCapabilities" name="signatureHelpClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SignatureHelpClientCapabilities {
-	/**
-	 * Whether signature help supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports the following `SignatureInformation`
-	 * specific properties.
-	 */
-	signatureInformation?: {
-		/**
-		 * Client supports the follow content formats for the documentation
-		 * property. The order describes the preferred format of the client.
-		 */
-		documentationFormat?: MarkupKind[];
-
-		/**
-		 * Client capabilities specific to parameter information.
-		 */
-		parameterInformation?: {
-			/**
-			 * The client supports processing label offsets instead of a
-			 * simple label string.
-			 *
-			 * @since 3.14.0
-			 */
-			labelOffsetSupport?: boolean;
-		};
-
-		/**
-		 * The client supports the `activeParameter` property on
-		 * `SignatureInformation` literal.
-		 *
-		 * @since 3.16.0
-		 */
-		activeParameterSupport?: boolean;
-	};
-
-	/**
-	 * The client supports to send additional context information for a
-	 * `textDocument/signatureHelp` request. A client that opts into
-	 * contextSupport will also support the `retriggerCharacters` on
-	 * `SignatureHelpOptions`.
-	 *
-	 * @since 3.15.0
-	 */
-	contextSupport?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `signatureHelpProvider`
-* property type: `SignatureHelpOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#signatureHelpOptions" name="signatureHelpOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SignatureHelpOptions extends WorkDoneProgressOptions {
-	/**
-	 * The characters that trigger signature help
-	 * automatically.
-	 */
-	triggerCharacters?: string[];
-
-	/**
-	 * List of characters that re-trigger signature help.
-	 *
-	 * These trigger characters are only active when signature help is already
-	 * showing. All trigger characters are also counted as re-trigger
-	 * characters.
-	 *
-	 * @since 3.15.0
-	 */
-	retriggerCharacters?: string[];
-}
-```
-
-_Registration Options_: `SignatureHelpRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#signatureHelpRegistrationOptions" name="signatureHelpRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SignatureHelpRegistrationOptions
-	extends TextDocumentRegistrationOptions, SignatureHelpOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/signatureHelp`
-* params: `SignatureHelpParams` defined as follows:
-
-<div class="anchorHolder"><a href="#signatureHelpParams" name="signatureHelpParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface SignatureHelpParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-	/**
-	 * The signature help context. This is only available if the client
-	 * specifies to send this using the client capability
-	 * `textDocument.signatureHelp.contextSupport === true`
-	 *
-	 * @since 3.15.0
-	 */
-	context?: SignatureHelpContext;
-}
-```
-
-<div class="anchorHolder"><a href="#signatureHelpTriggerKind" name="signatureHelpTriggerKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * How a signature help was triggered.
- *
- * @since 3.15.0
- */
-export namespace SignatureHelpTriggerKind {
-	/**
-	 * Signature help was invoked manually by the user or by a command.
-	 */
-	export const Invoked: 1 = 1;
-	/**
-	 * Signature help was triggered by a trigger character.
-	 */
-	export const TriggerCharacter: 2 = 2;
-	/**
-	 * Signature help was triggered by the cursor moving or by the document
-	 * content changing.
-	 */
-	export const ContentChange: 3 = 3;
-}
-export type SignatureHelpTriggerKind = 1 | 2 | 3;
-```
-
-<div class="anchorHolder"><a href="#signatureHelpContext" name="signatureHelpContext" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Additional information about the context in which a signature help request
- * was triggered.
- *
- * @since 3.15.0
- */
-export interface SignatureHelpContext {
-	/**
-	 * Action that caused signature help to be triggered.
-	 */
-	triggerKind: SignatureHelpTriggerKind;
-
-	/**
-	 * Character that caused signature help to be triggered.
-	 *
-	 * This is undefined when triggerKind !==
-	 * SignatureHelpTriggerKind.TriggerCharacter
-	 */
-	triggerCharacter?: string;
-
-	/**
-	 * `true` if signature help was already showing when it was triggered.
-	 *
-	 * Retriggers occur when the signature help is already active and can be
-	 * caused by actions such as typing a trigger character, a cursor move, or
-	 * document content changes.
-	 */
-	isRetrigger: boolean;
-
-	/**
-	 * The currently active `SignatureHelp`.
-	 *
-	 * The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field
-	 * updated based on the user navigating through available signatures.
-	 */
-	activeSignatureHelp?: SignatureHelp;
-}
-```
-
-_Response_:
-* result: `SignatureHelp` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#signatureHelp" name="signatureHelp" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Signature help represents the signature of something
- * callable. There can be multiple signature but only one
- * active and only one active parameter.
- */
-export interface SignatureHelp {
-	/**
-	 * One or more signatures. If no signatures are available the signature help
-	 * request should return `null`.
-	 */
-	signatures: SignatureInformation[];
-
-	/**
-	 * The active signature. If omitted or the value lies outside the
-	 * range of `signatures` the value defaults to zero or is ignore if
-	 * the `SignatureHelp` as no signatures.
-	 *
-	 * Whenever possible implementors should make an active decision about
-	 * the active signature and shouldn't rely on a default value.
-	 *
-	 * In future version of the protocol this property might become
-	 * mandatory to better express this.
-	 */
-	activeSignature?: uinteger;
-
-	/**
-	 * The active parameter of the active signature. If omitted or the value
-	 * lies outside the range of `signatures[activeSignature].parameters`
-	 * defaults to 0 if the active signature has parameters. If
-	 * the active signature has no parameters it is ignored.
-	 * In future version of the protocol this property might become
-	 * mandatory to better express the active parameter if the
-	 * active signature does have any.
-	 */
-	activeParameter?: uinteger;
-}
-```
-
-<div class="anchorHolder"><a href="#signatureInformation" name="signatureInformation" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents the signature of something callable. A signature
- * can have a label, like a function-name, a doc-comment, and
- * a set of parameters.
- */
-export interface SignatureInformation {
-	/**
-	 * The label of this signature. Will be shown in
-	 * the UI.
-	 */
-	label: string;
-
-	/**
-	 * The human-readable doc-comment of this signature. Will be shown
-	 * in the UI but can be omitted.
-	 */
-	documentation?: string | MarkupContent;
-
-	/**
-	 * The parameters of this signature.
-	 */
-	parameters?: ParameterInformation[];
-
-	/**
-	 * The index of the active parameter.
-	 *
-	 * If provided, this is used in place of `SignatureHelp.activeParameter`.
-	 *
-	 * @since 3.16.0
-	 */
-	activeParameter?: uinteger;
-}
-```
-
-<div class="anchorHolder"><a href="#parameterInformation" name="parameterInformation" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents a parameter of a callable-signature. A parameter can
- * have a label and a doc-comment.
- */
-export interface ParameterInformation {
-
-	/**
-	 * The label of this parameter information.
-	 *
-	 * Either a string or an inclusive start and exclusive end offsets within
-	 * its containing signature label. (see SignatureInformation.label). The
-	 * offsets are based on a UTF-16 string representation as `Position` and
-	 * `Range` does.
-	 *
-	 * *Note*: a label of type string should be a substring of its containing
-	 * signature label. Its intended use case is to highlight the parameter
-	 * label part in the `SignatureInformation.label`.
-	 */
-	label: string | [uinteger, uinteger];
-
-	/**
-	 * The human-readable doc-comment of this parameter. Will be shown
-	 * in the UI but can be omitted.
-	 */
-	documentation?: string | MarkupContent;
-}
-```
-
-* error: code and message set in case an exception happens during the signature help request.
-
-#### <a href="#textDocument_codeAction" name="textDocument_codeAction" class="anchor">Code Action Request (:leftwards_arrow_with_hook:)</a>
-
-The code action request is sent from the client to the server to compute commands for a given text document and range. These commands are typically code fixes to either fix problems or to beautify/refactor code. The result of a `textDocument/codeAction` request is an array of `Command` literals which are typically presented in the user interface. To ensure that a server is useful in many clients the commands specified in a code actions should be handled by the server and not by the client (see `workspace/executeCommand` and `ServerCapabilities.executeCommandProvider`). If the client supports providing edits with a code action then that mode should be used.
-
-*Since version 3.16.0:* a client can offer a server to delay the computation of code action properties during a 'textDocument/codeAction' request:
-
-This is useful for cases where it is expensive to compute the value of a property (for example the `edit` property). Clients signal this through the `codeAction.resolveSupport` capability which lists all properties a client can resolve lazily. The server capability `codeActionProvider.resolveProvider` signals that a server will offer a `codeAction/resolve` route. To help servers to uniquely identify a code action in the resolve request, a code action literal can optional carry a data property. This is also guarded by an additional client capability `codeAction.dataSupport`. In general, a client should offer data support if it offers resolve support. It should also be noted that servers shouldn't alter existing attributes of a code action in a codeAction/resolve request.
-
-> *Since version 3.8.0:* support for CodeAction literals to enable the following scenarios:
-
-- the ability to directly return a workspace edit from the code action request. This avoids having another server roundtrip to execute an actual code action. However server providers should be aware that if the code action is expensive to compute or the edits are huge it might still be beneficial if the result is simply a command and the actual edit is only computed when needed.
-- the ability to group code actions using a kind. Clients are allowed to ignore that information. However it allows them to better group code action for example into corresponding menus (e.g. all refactor code actions into a refactor menu).
-
-Clients need to announce their support for code action literals (e.g. literals of type `CodeAction`) and code action kinds via the corresponding client capability `codeAction.codeActionLiteralSupport`.
-
-_Client Capability_:
-* property name (optional): `textDocument.codeAction`
-* property type: `CodeActionClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#codeActionClientCapabilities" name="codeActionClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeActionClientCapabilities {
-	/**
-	 * Whether code action supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * The client supports code action literals as a valid
-	 * response of the `textDocument/codeAction` request.
-	 *
-	 * @since 3.8.0
-	 */
-	codeActionLiteralSupport?: {
-		/**
-		 * The code action kind is supported with the following value
-		 * set.
-		 */
-		codeActionKind: {
-
-			/**
-			 * The code action kind values the client supports. When this
-			 * property exists the client also guarantees that it will
-			 * handle values outside its set gracefully and falls back
-			 * to a default value when unknown.
-			 */
-			valueSet: CodeActionKind[];
-		};
-	};
-
-	/**
-	 * Whether code action supports the `isPreferred` property.
-	 *
-	 * @since 3.15.0
-	 */
-	isPreferredSupport?: boolean;
-
-	/**
-	 * Whether code action supports the `disabled` property.
-	 *
-	 * @since 3.16.0
-	 */
-	disabledSupport?: boolean;
-
-	/**
-	 * Whether code action supports the `data` property which is
-	 * preserved between a `textDocument/codeAction` and a
-	 * `codeAction/resolve` request.
-	 *
-	 * @since 3.16.0
-	 */
-	dataSupport?: boolean;
-
-
-	/**
-	 * Whether the client supports resolving additional code action
-	 * properties via a separate `codeAction/resolve` request.
-	 *
-	 * @since 3.16.0
-	 */
-	resolveSupport?: {
-		/**
-		 * The properties that a client can resolve lazily.
-		 */
-		properties: string[];
-	};
-
-	/**
-	 * Whether the client honors the change annotations in
-	 * text edits and resource operations returned via the
-	 * `CodeAction#edit` property by for example presenting
-	 * the workspace edit in the user interface and asking
-	 * for confirmation.
-	 *
-	 * @since 3.16.0
-	 */
-	honorsChangeAnnotations?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `codeActionProvider`
-* property type: `boolean | CodeActionOptions` where `CodeActionOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#codeActionOptions" name="codeActionOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeActionOptions extends WorkDoneProgressOptions {
-	/**
-	 * CodeActionKinds that this server may return.
-	 *
-	 * The list of kinds may be generic, such as `CodeActionKind.Refactor`,
-	 * or the server may list out every specific kind they provide.
-	 */
-	codeActionKinds?: CodeActionKind[];
-
-	/**
-	 * The server provides support to resolve additional
-	 * information for a code action.
-	 *
-	 * @since 3.16.0
-	 */
-	resolveProvider?: boolean;
-}
-```
-
-_Registration Options_: `CodeActionRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#codeActionRegistrationOptions" name="codeActionRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface CodeActionRegistrationOptions extends
-	TextDocumentRegistrationOptions, CodeActionOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/codeAction`
-* params: `CodeActionParams` defined as follows:
-
-<div class="anchorHolder"><a href="#codeActionParams" name="codeActionParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Params for the CodeActionRequest
- */
-export interface CodeActionParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The document in which the command was invoked.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The range for which the command was invoked.
-	 */
-	range: Range;
-
-	/**
-	 * Context carrying additional information.
-	 */
-	context: CodeActionContext;
-}
-```
-
-<div class="anchorHolder"><a href="#codeActionKind" name="codeActionKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The kind of a code action.
- *
- * Kinds are a hierarchical list of identifiers separated by `.`,
- * e.g. `"refactor.extract.function"`.
- *
- * The set of kinds is open and client needs to announce the kinds it supports
- * to the server during initialization.
- */
-export type CodeActionKind = string;
-
-/**
- * A set of predefined code action kinds.
- */
-export namespace CodeActionKind {
-
-	/**
-	 * Empty kind.
-	 */
-	export const Empty: CodeActionKind = '';
-
-	/**
-	 * Base kind for quickfix actions: 'quickfix'.
-	 */
-	export const QuickFix: CodeActionKind = 'quickfix';
-
-	/**
-	 * Base kind for refactoring actions: 'refactor'.
-	 */
-	export const Refactor: CodeActionKind = 'refactor';
-
-	/**
-	 * Base kind for refactoring extraction actions: 'refactor.extract'.
-	 *
-	 * Example extract actions:
-	 *
-	 * - Extract method
-	 * - Extract function
-	 * - Extract variable
-	 * - Extract interface from class
-	 * - ...
-	 */
-	export const RefactorExtract: CodeActionKind = 'refactor.extract';
-
-	/**
-	 * Base kind for refactoring inline actions: 'refactor.inline'.
-	 *
-	 * Example inline actions:
-	 *
-	 * - Inline function
-	 * - Inline variable
-	 * - Inline constant
-	 * - ...
-	 */
-	export const RefactorInline: CodeActionKind = 'refactor.inline';
-
-	/**
-	 * Base kind for refactoring rewrite actions: 'refactor.rewrite'.
-	 *
-	 * Example rewrite actions:
-	 *
-	 * - Convert JavaScript function to class
-	 * - Add or remove parameter
-	 * - Encapsulate field
-	 * - Make method static
-	 * - Move method to base class
-	 * - ...
-	 */
-	export const RefactorRewrite: CodeActionKind = 'refactor.rewrite';
-
-	/**
-	 * Base kind for source actions: `source`.
-	 *
-	 * Source code actions apply to the entire file.
-	 */
-	export const Source: CodeActionKind = 'source';
-
-	/**
-	 * Base kind for an organize imports source action:
-	 * `source.organizeImports`.
-	 */
-	export const SourceOrganizeImports: CodeActionKind =
-		'source.organizeImports';
-
-	/**
-	 * Base kind for a 'fix all' source action: `source.fixAll`.
-	 *
-	 * 'Fix all' actions automatically fix errors that have a clear fix that
-	 * do not require user input. They should not suppress errors or perform
-	 * unsafe fixes such as generating new types or classes.
-	 *
-	 * @since 3.17.0
-	 */
-	export const SourceFixAll: CodeActionKind = 'source.fixAll';
-}
-```
-
-<div class="anchorHolder"><a href="#codeActionContext" name="codeActionContext" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Contains additional diagnostic information about the context in which
- * a code action is run.
- */
-export interface CodeActionContext {
-	/**
-	 * An array of diagnostics known on the client side overlapping the range
-	 * provided to the `textDocument/codeAction` request. They are provided so
-	 * that the server knows which errors are currently presented to the user
-	 * for the given range. There is no guarantee that these accurately reflect
-	 * the error state of the resource. The primary parameter
-	 * to compute code actions is the provided range.
-	 */
-	diagnostics: Diagnostic[];
-
-	/**
-	 * Requested kind of actions to return.
-	 *
-	 * Actions not of this kind are filtered out by the client before being
-	 * shown. So servers can omit computing them.
-	 */
-	only?: CodeActionKind[];
-
-	/**
-	 * The reason why code actions were requested.
-	 *
-	 * @since 3.17.0
-	 */
-	triggerKind?: CodeActionTriggerKind;
-}
-```
-
-<div class="anchorHolder"><a href="#codeActionTriggerKind" name="codeActionTriggerKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The reason why code actions were requested.
- *
- * @since 3.17.0
- */
-export namespace CodeActionTriggerKind {
-	/**
-	 * Code actions were explicitly requested by the user or by an extension.
-	 */
-	export const Invoked: 1 = 1;
-
-	/**
-	 * Code actions were requested automatically.
-	 *
-	 * This typically happens when current selection in a file changes, but can
-	 * also be triggered when file content changes.
-	 */
-	export const Automatic: 2 = 2;
-}
-
-export type CodeActionTriggerKind = 1 | 2;
-```
-
-_Response_:
-* result: `(Command | CodeAction)[]` \| `null` where `CodeAction` is defined as follows:
-
-<div class="anchorHolder"><a href="#codeAction" name="codeAction" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A code action represents a change that can be performed in code, e.g. to fix
- * a problem or to refactor code.
- *
- * A CodeAction must set either `edit` and/or a `command`. If both are supplied,
- * the `edit` is applied first, then the `command` is executed.
- */
-export interface CodeAction {
-
-	/**
-	 * A short, human-readable, title for this code action.
-	 */
-	title: string;
-
-	/**
-	 * The kind of the code action.
-	 *
-	 * Used to filter code actions.
-	 */
-	kind?: CodeActionKind;
-
-	/**
-	 * The diagnostics that this code action resolves.
-	 */
-	diagnostics?: Diagnostic[];
-
-	/**
-	 * Marks this as a preferred action. Preferred actions are used by the
-	 * `auto fix` command and can be targeted by keybindings.
-	 *
-	 * A quick fix should be marked preferred if it properly addresses the
-	 * underlying error. A refactoring should be marked preferred if it is the
-	 * most reasonable choice of actions to take.
-	 *
-	 * @since 3.15.0
-	 */
-	isPreferred?: boolean;
-
-	/**
-	 * Marks that the code action cannot currently be applied.
-	 *
-	 * Clients should follow the following guidelines regarding disabled code
-	 * actions:
-	 *
-	 * - Disabled code actions are not shown in automatic lightbulbs code
-	 *   action menus.
-	 *
-	 * - Disabled actions are shown as faded out in the code action menu when
-	 *   the user request a more specific type of code action, such as
-	 *   refactorings.
-	 *
-	 * - If the user has a keybinding that auto applies a code action and only
-	 *   a disabled code actions are returned, the client should show the user
-	 *   an error message with `reason` in the editor.
-	 *
-	 * @since 3.16.0
-	 */
-	disabled?: {
-
-		/**
-		 * Human readable description of why the code action is currently
-		 * disabled.
-		 *
-		 * This is displayed in the code actions UI.
-		 */
-		reason: string;
-	};
-
-	/**
-	 * The workspace edit this code action performs.
-	 */
-	edit?: WorkspaceEdit;
-
-	/**
-	 * A command this code action executes. If a code action
-	 * provides an edit and a command, first the edit is
-	 * executed and then the command.
-	 */
-	command?: Command;
-
-	/**
-	 * A data entry field that is preserved on a code action between
-	 * a `textDocument/codeAction` and a `codeAction/resolve` request.
-	 *
-	 * @since 3.16.0
-	 */
-	data?: LSPAny;
-}
-```
-* partial result: `(Command | CodeAction)[]`
-* error: code and message set in case an exception happens during the code action request.
-
-#### <a href="#codeAction_resolve" name="codeAction_resolve" class="anchor">Code Action Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The request is sent from the client to the server to resolve additional information for a given code action. This is usually used to compute
-the `edit` property of a code action to avoid its unnecessary computation during the `textDocument/codeAction` request.
-
-Consider the clients announces the `edit` property as a property that can be resolved lazy using the client capability
-
-```typescript
-textDocument.codeAction.resolveSupport = { properties: ['edit'] };
-```
-
-then a code action
-
-```typescript
-{
-    "title": "Do Foo"
-}
-```
-
-needs to be resolved using the `codeAction/resolve` request before it can be applied.
-
-_Client Capability_:
-* property name (optional): `textDocument.codeAction.resolveSupport`
-* property type: `{ properties: string[]; }`
-
-_Request_:
-* method: `codeAction/resolve`
-* params: `CodeAction`
-
-_Response_:
-* result: `CodeAction`
-* error: code and message set in case an exception happens during the completion resolve request.
-
-#### <a href="#textDocument_documentColor" name="textDocument_documentColor" class="anchor">Document Color Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.6.0*
-
-The document color request is sent from the client to the server to list all color references found in a given text document. Along with the range, a color value in RGB is returned.
-
-Clients can use the result to decorate color references in an editor. For example:
-- Color boxes showing the actual color next to the reference
-- Show a color picker when a color reference is edited
-
-_Client Capability_:
-* property name (optional): `textDocument.colorProvider`
-* property type: `DocumentColorClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentColorClientCapabilities" name="documentColorClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentColorClientCapabilities {
-	/**
-	 * Whether document color supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `colorProvider`
-* property type: `boolean | DocumentColorOptions | DocumentColorRegistrationOptions` where `DocumentColorOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#documentColorOptions" name="documentColorOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentColorOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DocumentColorRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentColorRegistrationOptions" name="documentColorRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentColorRegistrationOptions extends
-	TextDocumentRegistrationOptions, StaticRegistrationOptions,
-	DocumentColorOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/documentColor`
-* params: `DocumentColorParams` defined as follows
-
-<div class="anchorHolder"><a href="#documentColorParams" name="documentColorParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DocumentColorParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-}
-```
-
-_Response_:
-* result: `ColorInformation[]` defined as follows:
-
-<div class="anchorHolder"><a href="#colorInformation" name="colorInformation" class="linkableAnchor"></a></div>
-
-```typescript
-interface ColorInformation {
-	/**
-	 * The range in the document where this color appears.
-	 */
-	range: Range;
-
-	/**
-	 * The actual color value for this color range.
-	 */
-	color: Color;
-}
-```
-
-<div class="anchorHolder"><a href="#color" name="color" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents a color in RGBA space.
- */
-interface Color {
-
-	/**
-	 * The red component of this color in the range [0-1].
-	 */
-	readonly red: decimal;
-
-	/**
-	 * The green component of this color in the range [0-1].
-	 */
-	readonly green: decimal;
-
-	/**
-	 * The blue component of this color in the range [0-1].
-	 */
-	readonly blue: decimal;
-
-	/**
-	 * The alpha component of this color in the range [0-1].
-	 */
-	readonly alpha: decimal;
-}
-```
-* partial result: `ColorInformation[]`
-* error: code and message set in case an exception happens during the 'textDocument/documentColor' request
-
-#### <a href="#textDocument_colorPresentation" name="textDocument_colorPresentation" class="anchor">Color Presentation Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.6.0*
-
-The color presentation request is sent from the client to the server to obtain a list of presentations for a color value at a given location. Clients can use the result to
-- modify a color reference.
-- show in a color picker and let users pick one of the presentations
-
-This request has no special capabilities and registration options since it is send as a resolve request for the `textDocument/documentColor` request.
-
-_Request_:
-
-* method: `textDocument/colorPresentation`
-* params: `ColorPresentationParams` defined as follows
-
-<div class="anchorHolder"><a href="#colorPresentationParams" name="colorPresentationParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface ColorPresentationParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * The text document.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The color information to request presentations for.
-	 */
-	color: Color;
-
-	/**
-	 * The range where the color would be inserted. Serves as a context.
-	 */
-	range: Range;
-}
-```
-
-_Response_:
-* result: `ColorPresentation[]` defined as follows:
-
-<div class="anchorHolder"><a href="#colorPresentation" name="colorPresentation" class="linkableAnchor"></a></div>
-
-```typescript
-interface ColorPresentation {
-	/**
-	 * The label of this color presentation. It will be shown on the color
-	 * picker header. By default this is also the text that is inserted when
-	 * selecting this color presentation.
-	 */
-	label: string;
-	/**
-	 * An [edit](#TextEdit) which is applied to a document when selecting
-	 * this presentation for the color. When `falsy` the
-	 * [label](#ColorPresentation.label) is used.
-	 */
-	textEdit?: TextEdit;
-	/**
-	 * An optional array of additional [text edits](#TextEdit) that are applied
-	 * when selecting this color presentation. Edits must not overlap with the
-	 * main [edit](#ColorPresentation.textEdit) nor with themselves.
-	 */
-	additionalTextEdits?: TextEdit[];
-}
-```
-
-* partial result: `ColorPresentation[]`
-* error: code and message set in case an exception happens during the 'textDocument/colorPresentation' request
-
-#### <a href="#textDocument_formatting" name="textDocument_formatting" class="anchor">Document Formatting Request  (:leftwards_arrow_with_hook:)</a>
-
-The document formatting request is sent from the client to the server to format a whole document.
-
-_Client Capability_:
-* property name (optional): `textDocument.formatting`
-* property type: `DocumentFormattingClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentFormattingClientCapabilities" name="documentFormattingClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentFormattingClientCapabilities {
-	/**
-	 * Whether formatting supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentFormattingProvider`
-* property type: `boolean | DocumentFormattingOptions` where `DocumentFormattingOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#documentFormattingOptions" name="documentFormattingOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentFormattingOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentFormattingRegistrationOptions" name="documentFormattingRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentFormattingRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentFormattingOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/formatting`
-* params: `DocumentFormattingParams` defined as follows
-
-<div class="anchorHolder"><a href="#documentFormattingParams" name="documentFormattingParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DocumentFormattingParams extends WorkDoneProgressParams {
-	/**
-	 * The document to format.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The format options.
-	 */
-	options: FormattingOptions;
-}
-```
-
-<div class="anchorHolder"><a href="#formattingOptions" name="formattingOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Value-object describing what options formatting should use.
- */
-interface FormattingOptions {
-	/**
-	 * Size of a tab in spaces.
-	 */
-	tabSize: uinteger;
-
-	/**
-	 * Prefer spaces over tabs.
-	 */
-	insertSpaces: boolean;
-
-	/**
-	 * Trim trailing whitespace on a line.
-	 *
-	 * @since 3.15.0
-	 */
-	trimTrailingWhitespace?: boolean;
-
-	/**
-	 * Insert a newline character at the end of the file if one does not exist.
-	 *
-	 * @since 3.15.0
-	 */
-	insertFinalNewline?: boolean;
-
-	/**
-	 * Trim all newlines after the final newline at the end of the file.
-	 *
-	 * @since 3.15.0
-	 */
-	trimFinalNewlines?: boolean;
-
-	/**
-	 * Signature for further properties.
-	 */
-	[key: string]: boolean | integer | string;
-}
-```
-
-_Response_:
-* result: [`TextEdit[]`](#textEdit) \| `null` describing the modification to the document to be formatted.
-* error: code and message set in case an exception happens during the formatting request.
-
-#### <a href="#textDocument_rangeFormatting" name="textDocument_rangeFormatting" class="anchor">Document Range Formatting Request (:leftwards_arrow_with_hook:)</a>
-
-The document range formatting request is sent from the client to the server to format a given range in a document.
-
-_Client Capability_:
-* property name (optional): `textDocument.rangeFormatting`
-* property type: `DocumentRangeFormattingClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentRangeFormattingClientCapabilities" name="documentRangeFormattingClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentRangeFormattingClientCapabilities {
-	/**
-	 * Whether formatting supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentRangeFormattingProvider`
-* property type: `boolean | DocumentRangeFormattingOptions` where `DocumentRangeFormattingOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#documentRangeFormattingOptions" name="documentRangeFormattingOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentRangeFormattingOptions extends
-	WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentRangeFormattingRegistrationOptions" name="documentRangeFormattingRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentRangeFormattingRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentRangeFormattingOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/rangeFormatting`,
-* params: `DocumentRangeFormattingParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentRangeFormattingParams" name="documentRangeFormattingParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DocumentRangeFormattingParams extends WorkDoneProgressParams {
-	/**
-	 * The document to format.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The range to format
-	 */
-	range: Range;
-
-	/**
-	 * The format options
-	 */
-	options: FormattingOptions;
-}
-```
-
-_Response_:
-* result: [`TextEdit[]`](#textEdit) \| `null` describing the modification to the document to be formatted.
-* error: code and message set in case an exception happens during the range formatting request.
-
-#### <a href="#textDocument_onTypeFormatting" name="textDocument_onTypeFormatting" class="anchor">Document on Type Formatting Request (:leftwards_arrow_with_hook:)</a>
-
-The document on type formatting request is sent from the client to the server to format parts of the document during typing.
-
-_Client Capability_:
-* property name (optional): `textDocument.onTypeFormatting`
-* property type: `DocumentOnTypeFormattingClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#documentOnTypeFormattingClientCapabilities" name="documentOnTypeFormattingClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentOnTypeFormattingClientCapabilities {
-	/**
-	 * Whether on type formatting supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `documentOnTypeFormattingProvider`
-* property type: `DocumentOnTypeFormattingOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentOnTypeFormattingOptions" name="documentOnTypeFormattingOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentOnTypeFormattingOptions {
-	/**
-	 * A character on which formatting should be triggered, like `{`.
-	 */
-	firstTriggerCharacter: string;
-
-	/**
-	 * More trigger characters.
-	 */
-	moreTriggerCharacter?: string[];
-}
-```
-
-_Registration Options_: `DocumentOnTypeFormattingRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#documentOnTypeFormattingRegistrationOptions" name="documentOnTypeFormattingRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DocumentOnTypeFormattingRegistrationOptions extends
-	TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/onTypeFormatting`
-* params: `DocumentOnTypeFormattingParams` defined as follows:
-
-<div class="anchorHolder"><a href="#documentOnTypeFormattingParams" name="documentOnTypeFormattingParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DocumentOnTypeFormattingParams {
-
-	/**
-	 * The document to format.
-	 */
-	textDocument: TextDocumentIdentifier;
-
-	/**
-	 * The position around which the on type formatting should happen.
-	 * This is not necessarily the exact position where the character denoted
-	 * by the property `ch` got typed.
-	 */
-	position: Position;
-
-	/**
-	 * The character that has been typed that triggered the formatting
-	 * on type request. That is not necessarily the last character that
-	 * got inserted into the document since the client could auto insert
-	 * characters as well (e.g. like automatic brace completion).
-	 */
-	ch: string;
-
-	/**
-	 * The formatting options.
-	 */
-	options: FormattingOptions;
-}
-```
-
-_Response_:
-* result: [`TextEdit[]`](#textEdit) \| `null` describing the modification to the document.
-* error: code and message set in case an exception happens during the range formatting request.
-
-#### <a href="#textDocument_rename" name="textDocument_rename" class="anchor">Rename Request (:leftwards_arrow_with_hook:)</a>
-
-The rename request is sent from the client to the server to ask the server to compute a workspace change so that the client can perform a workspace-wide rename of a symbol.
-
-_Client Capability_:
-* property name (optional): `textDocument.rename`
-* property type: `RenameClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#prepareSupportDefaultBehavior" name="prepareSupportDefaultBehavior" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace PrepareSupportDefaultBehavior {
-	/**
-	 * The client's default behavior is to select the identifier
-	 * according to the language's syntax rule.
-	 */
-	 export const Identifier: 1 = 1;
-}
-```
-
-<div class="anchorHolder"><a href="#renameClientCapabilities" name="renameClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface RenameClientCapabilities {
-	/**
-	 * Whether rename supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Client supports testing for validity of rename operations
-	 * before execution.
-	 *
-	 * @since version 3.12.0
-	 */
-	prepareSupport?: boolean;
-
-	/**
-	 * Client supports the default behavior result
-	 * (`{ defaultBehavior: boolean }`).
-	 *
-	 * The value indicates the default behavior used by the
-	 * client.
-	 *
-	 * @since version 3.16.0
-	 */
-	prepareSupportDefaultBehavior?: PrepareSupportDefaultBehavior;
-
-	/**
-	 * Whether th client honors the change annotations in
-	 * text edits and resource operations returned via the
-	 * rename request's workspace edit by for example presenting
-	 * the workspace edit in the user interface and asking
-	 * for confirmation.
-	 *
-	 * @since 3.16.0
-	 */
-	honorsChangeAnnotations?: boolean;
-}
-```
-
-_Server Capability_:
-* property name (optional): `renameProvider`
-* property type: `boolean | RenameOptions` where `RenameOptions` is defined as follows:
-
-`RenameOptions` may only be specified if the client states that it supports `prepareSupport` in its initial `initialize` request.
-
-<div class="anchorHolder"><a href="#renameOptions" name="renameOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface RenameOptions extends WorkDoneProgressOptions {
-	/**
-	 * Renames should be checked and tested before being executed.
-	 */
-	prepareProvider?: boolean;
-}
-```
-
-_Registration Options_: `RenameRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#renameRegistrationOptions" name="renameRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface RenameRegistrationOptions extends
-	TextDocumentRegistrationOptions, RenameOptions {
-}
-```
-
-_Request_:
-* method: `textDocument/rename`
-* params: `RenameParams` defined as follows
-
-<div class="anchorHolder"><a href="#renameParams" name="renameParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface RenameParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-	/**
-	 * The new name of the symbol. If the given name is not valid the
-	 * request must return a [ResponseError](#ResponseError) with an
-	 * appropriate message set.
-	 */
-	newName: string;
-}
-```
-
-_Response_:
-* result: [`WorkspaceEdit`](#workspaceedit) \| `null` describing the modification to the workspace. `null` should be treated the same was as [`WorkspaceEdit`](#workspaceedit) with no changes (no change was required).
-* error: code and message set in case when rename could not be performed for any reason. Examples include: there is nothing at given `position` to rename (like a space), given symbol does not support renaming by the server or the code is invalid (e.g. does not compile).
-
-#### <a href="#textDocument_prepareRename" name="textDocument_prepareRename" class="anchor">Prepare Rename Request (:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.12.0*
-
-The prepare rename request is sent from the client to the server to setup and test the validity of a rename operation at a given location.
-
-_Request_:
-* method: `textDocument/prepareRename`
-* params: `PrepareRenameParams` defined as follows:
-
-<div class="anchorHolder"><a href="#prepareRenameParams" name="prepareRenameParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface PrepareRenameParams extends TextDocumentPositionParams, WorkDoneProgressParams {
-}
-```
-
-_Response_:
-* result: `Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null` describing a [`Range`](#range) of the string to rename and optionally a placeholder text of the string content to be renamed. If `{ defaultBehavior: boolean }` is returned (since 3.16) the rename position is valid and the client should use its default behavior to compute the rename range. If `null` is returned then it is deemed that a 'textDocument/rename' request is not valid at the given position.
-* error: code and message set in case the element can't be renamed. Clients should show the information in their user interface.
-
-#### <a href="#textDocument_linkedEditingRange" name="textDocument_linkedEditingRange" class="anchor">Linked Editing Range(:leftwards_arrow_with_hook:)</a>
-
-> *Since version 3.16.0*
-
-The linked editing request is sent from the client to the server to return for a given position in a document the range of the symbol at the position and all ranges that have the same content. Optionally a word pattern can be returned to describe valid contents. A rename to one of the ranges can be applied to all other ranges if the new content is valid. If no result-specific word pattern is provided, the word pattern from the client's language configuration is used.
-
-_Client Capabilities_:
-
-* property name (optional): `textDocument.linkedEditingRange`
-* property type: `LinkedEditingRangeClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#linkedEditingRangeClientCapabilities" name="linkedEditingRangeClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface LinkedEditingRangeClientCapabilities {
-	/**
-	 * Whether implementation supports dynamic registration.
-	 * If this is set to `true` the client supports the new
-	 * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
-	 * return value for the corresponding server capability as well.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-
-* property name (optional): `linkedEditingRangeProvider`
-* property type: `boolean` \| `LinkedEditingRangeOptions` \| `LinkedEditingRangeRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#linkedEditingRangeOptions" name="linkedEditingRangeOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface LinkedEditingRangeOptions extends WorkDoneProgressOptions {
-}
-```
-
-_Registration Options_: `LinkedEditingRangeRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#linkedEditingRangeRegistrationOptions" name="linkedEditingRangeRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface LinkedEditingRangeRegistrationOptions extends
-	TextDocumentRegistrationOptions, LinkedEditingRangeOptions,
-	StaticRegistrationOptions {
-}
-```
-
-_Request_:
-
-* method: `textDocument/linkedEditingRange`
-* params: `LinkedEditingRangeParams` defined as follows:
-
-<div class="anchorHolder"><a href="#linkedEditingRangeParams" name="linkedEditingRangeParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface LinkedEditingRangeParams extends TextDocumentPositionParams,
-	WorkDoneProgressParams {
-}
-```
-
-_Response_:
-
-* result: `LinkedEditingRanges` \| `null` defined as follows:
-
-<div class="anchorHolder"><a href="#linkedEditingRanges" name="linkedEditingRanges" class="linkableAnchor"></a></div>
-
-```typescript
-export interface LinkedEditingRanges {
-	/**
-	 * A list of ranges that can be renamed together. The ranges must have
-	 * identical length and contain identical text content. The ranges cannot
-	 * overlap.
-	 */
-	ranges: Range[];
-
-	/**
-	 * An optional word pattern (regular expression) that describes valid
-	 * contents for the given ranges. If no pattern is provided, the client
-	 * configuration's word pattern will be used.
-	 */
-	wordPattern?: string;
-}
-```
-* error: code and message set in case an exception happens during the 'textDocument/linkedEditingRange' request
-
-
-### <a href="#workspaceFeatures" name="workspaceFeatures" class="anchor">Workspace Features</a>
-
-#### <a href="#workspace_symbol" name="workspace_symbol" class="anchor">Workspace Symbols Request (:leftwards_arrow_with_hook:)</a>
-
-The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string. Since 3.17.0 servers can also provider a handler for `workspaceSymbol/resolve` requests. This allows servers to return workspace symbols without a range for a `workspace/symbol` request. Clients then need to resolve the range when necessary using the `workspaceSymbol/resolve` request. Servers can only use this new model if clients advertise support for it via the `workspace.symbol.resolveSupport` capability.
-
-_Client Capability_:
-* property path (optional): `workspace.symbol`
-* property type: `WorkspaceSymbolClientCapabilities` defined as follows:
-
-```typescript
-interface WorkspaceSymbolClientCapabilities {
-	/**
-	 * Symbol request supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Specific capabilities for the `SymbolKind` in the `workspace/symbol`
-	 * request.
-	 */
-	symbolKind?: {
-		/**
-		 * The symbol kind values the client supports. When this
-		 * property exists the client also guarantees that it will
-		 * handle values outside its set gracefully and falls back
-		 * to a default value when unknown.
-		 *
-		 * If this property is not present the client only supports
-		 * the symbol kinds from `File` to `Array` as defined in
-		 * the initial version of the protocol.
-		 */
-		valueSet?: SymbolKind[];
-	};
-
-	/**
-	 * The client supports tags on `SymbolInformation` and `WorkspaceSymbol`.
-	 * Clients supporting tags have to handle unknown tags gracefully.
-	 *
-	 * @since 3.16.0
-	 */
-	tagSupport?: {
-		/**
-		 * The tags supported by the client.
-		 */
-		valueSet: SymbolTag[];
-	};
-
-	/**
-	 * The client support partial workspace symbols. The client will send the
-	 * request `workspaceSymbol/resolve` to the server to resolve additional
-	 * properties.
-	 *
-	 * @since 3.17.0 - proposedState
-	 */
-	resolveSupport?: {
-		/**
-		 * The properties that a client can resolve lazily. Usually
-		 * `location.range`
-		 */
-		properties: string[];
-	};
-}
-```
-
-_Server Capability_:
-* property path (optional): `workspaceSymbolProvider`
-* property type: `boolean | WorkspaceSymbolOptions` where `WorkspaceSymbolOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceSymbolOptions" name="workspaceSymbolOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkspaceSymbolOptions extends WorkDoneProgressOptions {
-	/**
-	 * The server provides support to resolve additional
-	 * information for a workspace symbol.
-	 *
-	 * @since 3.17.0
-	 */
-	resolveProvider?: boolean;
-}
-```
-
-_Registration Options_: `WorkspaceSymbolRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceSymbolRegistrationOptions" name="workspaceSymbolRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkspaceSymbolRegistrationOptions
-	extends WorkspaceSymbolOptions {
-}
-```
-
-_Request_:
-* method: 'workspace/symbol'
-* params: `WorkspaceSymbolParams` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceSymbolParams" name="workspaceSymbolParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The parameters of a Workspace Symbol Request.
- */
-interface WorkspaceSymbolParams extends WorkDoneProgressParams,
-	PartialResultParams {
-	/**
-	 * A query string to filter symbols by. Clients may send an empty
-	 * string here to request all symbols.
-	 */
-	query: string;
-}
-```
-
-_Response_:
-* result: `SymbolInformation[]` \| `WorkspaceSymbol[]` \| `null`. See above for the definition of `SymbolInformation`. It is recommended that you use the new `WorkspaceSymbol`. However whether the workspace symbol can return a location without a range depends on the client capability `workspace.symbol.resolveSupport`. `WorkspaceSymbol`which is defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceSymbol" name="workspaceSymbol" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A special workspace symbol that supports locations without a range
- *
- * @since 3.17.0
- */
-export interface WorkspaceSymbol {
-	/**
-	 * The name of this symbol.
-	 */
-	name: string;
-
-	/**
-	 * The kind of this symbol.
-	 */
-	kind: SymbolKind;
-
-	/**
-	 * Tags for this completion item.
-	 */
-	tags?: SymbolTag[];
-
-	/**
-	 * The location of this symbol. Whether a server is allowed to
-	 * return a location without a range depends on the client
-	 * capability `workspace.symbol.resolveSupport`.
-	 *
-	 * See also `SymbolInformation.location`.
-	 */
-	location: Location | { uri: DocumentUri };
-
-	/**
-	 * The name of the symbol containing this symbol. This information is for
-	 * user interface purposes (e.g. to render a qualifier in the user interface
-	 * if necessary). It can't be used to re-infer a hierarchy for the document
-	 * symbols.
-	 */
-	containerName?: string;
-}
-```
-* partial result: `SymbolInformation[]` \| `WorkspaceSymbol[]` as defined above.
-* error: code and message set in case an exception happens during the workspace symbol request.
-
-#### <a href="#workspace_symbolResolve" name="workspace_symbolResolve" class="anchor">Workspace Symbol Resolve Request (:leftwards_arrow_with_hook:)</a>
-
-The request is sent from the client to the server to resolve additional information for a given workspace symbol.
-
-_Request_:
-* method: 'workspaceSymbol/resolve'
-* params: `WorkspaceSymbol`
-
-_Response_:
-* result: `WorkspaceSymbol`
-* error: code and message set in case an exception happens during the workspace symbol resolve request.
-
-#### <a href="#workspace_configuration" name="workspace_configuration" class="anchor">Configuration Request (:arrow_right_hook:)</a>
-
-> *Since version 3.6.0*
-
-The `workspace/configuration` request is sent from the server to the client to fetch configuration settings from the client. The request can fetch several configuration settings in one roundtrip. The order of the returned configuration settings correspond to the order of the passed `ConfigurationItems` (e.g. the first item in the response is the result for the first configuration item in the params).
-
-A `ConfigurationItem` consists of the configuration section to ask for and an additional scope URI. The configuration section asked for is defined by the server and doesn't necessarily need to correspond to the configuration store used by the client. So a server might ask for a configuration `cpp.formatterOptions` but the client stores the configuration in an XML store layout differently. It is up to the client to do the necessary conversion. If a scope URI is provided the client should return the setting scoped to the provided resource. If the client for example uses [EditorConfig](http://editorconfig.org/) to manage its settings the configuration should be returned for the passed resource URI. If the client can't provide a configuration setting for a given scope then `null` needs to be present in the returned array.
-
-_Client Capability_:
-* property path (optional): `workspace.configuration`
-* property type: `boolean`
-
-_Request_:
-* method: 'workspace/configuration'
-* params: `ConfigurationParams` defined as follows
-
-<div class="anchorHolder"><a href="#configurationParams" name="configurationParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ConfigurationParams {
-	items: ConfigurationItem[];
-}
-```
-
-<div class="anchorHolder"><a href="#configurationItem" name="configurationItem" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ConfigurationItem {
-	/**
-	 * The scope to get the configuration section for.
-	 */
-	scopeUri?: DocumentUri;
-
-	/**
-	 * The configuration section asked for.
-	 */
-	section?: string;
-}
-```
-
-_Response_:
-* result: LSPAny[]
-* error: code and message set in case an exception happens during the 'workspace/configuration' request
-
-#### <a href="#workspace_didChangeConfiguration" name="workspace_didChangeConfiguration" class="anchor">DidChangeConfiguration Notification (:arrow_right:)</a>
-
-A notification sent from the client to the server to signal the change of configuration settings.
-
-_Client Capability_:
-* property path (optional): `workspace.didChangeConfiguration`
-* property type: `DidChangeConfigurationClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeConfigurationClientCapabilities" name="didChangeConfigurationClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DidChangeConfigurationClientCapabilities {
-	/**
-	 * Did change configuration notification supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Notification_:
-* method: 'workspace/didChangeConfiguration',
-* params: `DidChangeConfigurationParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeConfigurationParams" name="didChangeConfigurationParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidChangeConfigurationParams {
-	/**
-	 * The actual changed settings
-	 */
-	settings: LSPAny;
-}
-```
-
-#### <a href="#workspace_workspaceFolders" name="workspace_workspaceFolders" class="anchor">Workspace folders request (:arrow_right_hook:)</a>
-
-> *Since version 3.6.0*
-
-Many tools support more than one root folder per workspace. Examples for this are VS Code's multi-root support, Atom's project folder support or Sublime's project support. If a client workspace consists of multiple roots then a server typically needs to know about this. The protocol up to now assumes one root folder which is announced to the server by the `rootUri` property of the `InitializeParams`. If the client supports workspace folders and announces them via the corresponding `workspaceFolders` client capability, the `InitializeParams` contain an additional property `workspaceFolders` with the configured workspace folders when the server starts.
-
-The `workspace/workspaceFolders` request is sent from the server to the client to fetch the current open list of workspace folders. Returns `null` in the response if only a single file is open in the tool. Returns an empty array if a workspace is open but no folders are configured.
-
-_Client Capability_:
-* property path (optional): `workspace.workspaceFolders`
-* property type: `boolean`
-
-_Server Capability_:
-* property path (optional): `workspace.workspaceFolders`
-* property type: `WorkspaceFoldersServerCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceFoldersServerCapabilities" name="workspaceFoldersServerCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkspaceFoldersServerCapabilities {
-	/**
-	 * The server has support for workspace folders
-	 */
-	supported?: boolean;
-
-	/**
-	 * Whether the server wants to receive workspace folder
-	 * change notifications.
-	 *
-	 * If a string is provided, the string is treated as an ID
-	 * under which the notification is registered on the client
-	 * side. The ID can be used to unregister for these events
-	 * using the `client/unregisterCapability` request.
-	 */
-	changeNotifications?: string | boolean;
-}
-```
-
-_Request_:
-* method: `workspace/workspaceFolders`
-* params: none
-
-_Response_:
-* result: `WorkspaceFolder[] | null` defined as follows:
-
-<div class="anchorHolder"><a href="#workspaceFolder" name="workspaceFolder" class="linkableAnchor"></a></div>
-
-```typescript
-export interface WorkspaceFolder {
-	/**
-	 * The associated URI for this workspace folder.
-	 */
-	uri: DocumentUri;
-
-	/**
-	 * The name of the workspace folder. Used to refer to this
-	 * workspace folder in the user interface.
-	 */
-	name: string;
-}
-```
-* error: code and message set in case an exception happens during the 'workspace/workspaceFolders' request
-
-#### <a href="#workspace_didChangeWorkspaceFolders" name="workspace_didChangeWorkspaceFolders" class="anchor">DidChangeWorkspaceFolders Notification (:arrow_right:)</a>
-
-> *Since version 3.6.0*
-
-The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server to inform the server about workspace folder configuration changes. The notification is sent by default if both _client capability_ `workspace.workspaceFolders` and the _server capability_ `workspace.workspaceFolders.supported` are true; or if the server has registered itself to receive this notification. To register for the `workspace/didChangeWorkspaceFolders` send a `client/registerCapability` request from the server to the client. The registration parameter must have a `registrations` item of the following form, where `id` is a unique id used to unregister the capability (the example uses a UUID):
-```ts
-{
-	id: "28c6150c-bd7b-11e7-abc4-cec278b6b50a",
-	method: "workspace/didChangeWorkspaceFolders"
-}
-```
-
-_Notification_:
-* method: 'workspace/didChangeWorkspaceFolders'
-* params: `DidChangeWorkspaceFoldersParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeWorkspaceFoldersParams" name="didChangeWorkspaceFoldersParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DidChangeWorkspaceFoldersParams {
-	/**
-	 * The actual workspace folder change event.
-	 */
-	event: WorkspaceFoldersChangeEvent;
-}
-```
-
-<div class="anchorHolder"><a href="#workspaceFoldersChangeEvent" name="workspaceFoldersChangeEvent" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The workspace folder change event.
- */
-export interface WorkspaceFoldersChangeEvent {
-	/**
-	 * The array of added workspace folders
-	 */
-	added: WorkspaceFolder[];
-
-	/**
-	 * The array of the removed workspace folders
-	 */
-	removed: WorkspaceFolder[];
-}
-```
-
-#### <a href="#workspace_willCreateFiles" name="workspace_willCreateFiles" class="anchor">WillCreateFiles Request (:leftwards_arrow_with_hook:)</a>
-
-The will create files request is sent from the client to the server before files are actually created as long as the creation is triggered from within the client either by a user action or by applying a workspace edit. The request can return a WorkspaceEdit which will be applied to workspace before the files are created. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep creates fast and reliable.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.willCreate`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/willCreateFiles` requests.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.willCreate`
-* property type: `FileOperationRegistrationOptions` where `FileOperationRegistrationOptions` is defined as follows:
-
-<div class="anchorHolder"><a href="#fileOperationRegistrationOptions" name="fileOperationRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The options to register for file operations.
- *
- * @since 3.16.0
- */
-interface FileOperationRegistrationOptions {
-	/**
-	 * The actual filters.
-	 */
-	filters: FileOperationFilter[];
-}
-```
-
-<div class="anchorHolder"><a href="#fileOperationPatternKind" name="fileOperationPatternKind" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A pattern kind describing if a glob pattern matches a file a folder or
- * both.
- *
- * @since 3.16.0
- */
-export namespace FileOperationPatternKind {
-	/**
-	 * The pattern matches a file only.
-	 */
-	export const file: 'file' = 'file';
-
-	/**
-	 * The pattern matches a folder only.
-	 */
-	export const folder: 'folder' = 'folder';
-}
-
-export type FileOperationPatternKind = 'file' | 'folder';
-```
-
-<div class="anchorHolder"><a href="#fileOperationPatternOptions" name="fileOperationPatternOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Matching options for the file operation pattern.
- *
- * @since 3.16.0
- */
-export interface FileOperationPatternOptions {
-
-	/**
-	 * The pattern should be matched ignoring casing.
-	 */
-	ignoreCase?: boolean;
-}
-```
-
-<div class="anchorHolder"><a href="#fileOperationPattern" name="fileOperationPattern" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A pattern to describe in which file operation requests or notifications
- * the server is interested in.
- *
- * @since 3.16.0
- */
-interface FileOperationPattern {
-	/**
-	 * The glob pattern to match. 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`)
-	 */
-	glob: string;
-
-	/**
-	 * Whether to match files or folders with this pattern.
-	 *
-	 * Matches both if undefined.
-	 */
-	matches?: FileOperationPatternKind;
-
-	/**
-	 * Additional options used during matching.
-	 */
-	options?: FileOperationPatternOptions;
-}
-```
-
-<div class="anchorHolder"><a href="#fileOperationFilter" name="fileOperationFilter" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A filter to describe in which file operation requests or notifications
- * the server is interested in.
- *
- * @since 3.16.0
- */
-export interface FileOperationFilter {
-
-	/**
-	 * A Uri like `file` or `untitled`.
-	 */
-	scheme?: string;
-
-	/**
-	 * The actual file operation pattern.
-	 */
-	pattern: FileOperationPattern;
-}
-```
-
-The capability indicates that the server is interested in receiving `workspace/willCreateFiles` requests.
-
-_Registration Options_: none
-
-_Request_:
-* method: 'workspace/willCreateFiles'
-* params: `CreateFilesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#createFilesParams" name="createFilesParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The parameters sent in notifications/requests for user-initiated creation
- * of files.
- *
- * @since 3.16.0
- */
-export interface CreateFilesParams {
-
-	/**
-	 * An array of all files/folders created in this operation.
-	 */
-	files: FileCreate[];
-}
-```
-
-<div class="anchorHolder"><a href="#fileCreate" name="fileCreate" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents information on a file/folder create.
- *
- * @since 3.16.0
- */
-export interface FileCreate {
-
-	/**
-	 * A file:// URI for the location of the file/folder being created.
-	 */
-	uri: string;
-}
-```
-
-_Response_:
-* result:`WorkspaceEdit` \| `null`
-* error: code and message set in case an exception happens during the `willCreateFiles` request.
-
-#### <a href="#workspace_didCreateFiles" name="workspace_didCreateFiles" class="anchor">DidCreateFiles Notification (:arrow_right:)</a>
-
-The did create files notification is sent from the client to the server when files were created from within the client.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.didCreate`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/didCreateFiles` notifications.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.didCreate`
-* property type: `FileOperationRegistrationOptions`
-
-The capability indicates that the server is interested in receiving `workspace/didCreateFiles` notifications.
-
-_Notification_:
-* method: 'workspace/didCreateFiles'
-* params: `CreateFilesParams`
-
-#### <a href="#workspace_willRenameFiles" name="workspace_willRenameFiles" class="anchor">WillRenameFiles Request (:leftwards_arrow_with_hook:)</a>
-
-The will rename files request is sent from the client to the server before files are actually renamed as long as the rename is triggered from within the client either by a user action or by applying a workspace edit. The request can return a WorkspaceEdit which will be applied to workspace before the files are renamed. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep renames fast and reliable.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.willRename`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/willRenameFiles` requests.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.willRename`
-* property type: `FileOperationRegistrationOptions`
-
-The capability indicates that the server is interested in receiving `workspace/willRenameFiles` requests.
-
-_Registration Options_: none
-
-_Request_:
-* method: 'workspace/willRenameFiles'
-* params: `RenameFilesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#renameFilesParams" name="renameFilesParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The parameters sent in notifications/requests for user-initiated renames
- * of files.
- *
- * @since 3.16.0
- */
-export interface RenameFilesParams {
-
-	/**
-	 * An array of all files/folders renamed in this operation. When a folder
-	 * is renamed, only the folder will be included, and not its children.
-	 */
-	files: FileRename[];
-}
-```
-
-<div class="anchorHolder"><a href="#fileRename" name="fileRename" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents information on a file/folder rename.
- *
- * @since 3.16.0
- */
-export interface FileRename {
-
-	/**
-	 * A file:// URI for the original location of the file/folder being renamed.
-	 */
-	oldUri: string;
-
-	/**
-	 * A file:// URI for the new location of the file/folder being renamed.
-	 */
-	newUri: string;
-}
-```
-
-_Response_:
-* result:`WorkspaceEdit` \| `null`
-* error: code and message set in case an exception happens during the `workspace/willRenameFiles` request.
-
-#### <a href="#workspace_didRenameFiles" name="workspace_didRenameFiles" class="anchor">DidRenameFiles Notification (:arrow_right:)</a>
-
-The did rename files notification is sent from the client to the server when files were renamed from within the client.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.didRename`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/didRenameFiles` notifications.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.didRename`
-* property type: `FileOperationRegistrationOptions`
-
-The capability indicates that the server is interested in receiving `workspace/didRenameFiles` notifications.
-
-_Notification_:
-* method: 'workspace/didRenameFiles'
-* params: `RenameFilesParams`
-
-#### <a href="#workspace_willDeleteFiles" name="workspace_willDeleteFiles" class="anchor">WillDeleteFiles Request (:leftwards_arrow_with_hook:)</a>
-
-The will delete files request is sent from the client to the server before files are actually deleted as long as the deletion is triggered from within the client either by a user action or by applying a workspace edit. The request can return a WorkspaceEdit which will be applied to workspace before the files are deleted. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep deletes fast and reliable.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.willDelete`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/willDeleteFiles` requests.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.willDelete`
-* property type: `FileOperationRegistrationOptions`
-
-The capability indicates that the server is interested in receiving `workspace/willDeleteFiles` requests.
-
-_Registration Options_: none
-
-_Request_:
-* method: `workspace/willDeleteFiles`
-* params: `DeleteFilesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#deleteFilesParams" name="deleteFilesParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The parameters sent in notifications/requests for user-initiated deletes
- * of files.
- *
- * @since 3.16.0
- */
-export interface DeleteFilesParams {
-
-	/**
-	 * An array of all files/folders deleted in this operation.
-	 */
-	files: FileDelete[];
-}
-```
-
-<div class="anchorHolder"><a href="#fileDelete" name="fileDelete" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Represents information on a file/folder delete.
- *
- * @since 3.16.0
- */
-export interface FileDelete {
-
-	/**
-	 * A file:// URI for the location of the file/folder being deleted.
-	 */
-	uri: string;
-}
-```
-
-_Response_:
-* result:`WorkspaceEdit` \| `null`
-* error: code and message set in case an exception happens during the `workspace/willDeleteFiles` request.
-
-#### <a href="#workspace_didDeleteFiles" name="workspace_didDeleteFiles" class="anchor">DidDeleteFiles Notification (:arrow_right:)</a>
-
-The did delete files notification is sent from the client to the server when files were deleted from within the client.
-
-_Client Capability_:
-* property name (optional): `workspace.fileOperations.didDelete`
-* property type: `boolean`
-
-The capability indicates that the client supports sending `workspace/didDeleteFiles` notifications.
-
-_Server Capability_:
-* property name (optional): `workspace.fileOperations.didDelete`
-* property type: `FileOperationRegistrationOptions`
-
-The capability indicates that the server is interested in receiving `workspace/didDeleteFiles` notifications.
-
-_Notification_:
-* method: 'workspace/didDeleteFiles'
-* params: `DeleteFilesParams`
-
-#### <a href="#workspace_didChangeWatchedFiles" name="workspace_didChangeWatchedFiles" class="anchor">DidChangeWatchedFiles Notification (:arrow_right:)</a>
-
-The watched files notification is sent from the client to the server when the client detects changes to files and folders watched by the language client (note although the name suggest that only file events are sent it is about file system events which include folders as well). It is recommended that servers register for these file system events using the registration mechanism. In former implementations clients pushed file events without the server actively asking for it.
-
-Servers are allowed to run their own file system watching mechanism and not rely on clients to provide file system events. However this is not recommended due to the following reasons:
-
-- to our experience getting file system watching on disk right is challenging, especially if it needs to be supported across multiple OSes.
-- file system watching is not for free especially if the implementation uses some sort of polling and keeps a file system tree in memory to compare time stamps (as for example some node modules do)
-- a client usually starts more than one server. If every server runs its own file system watching it can become a CPU or memory problem.
-- in general there are more server than client implementations. So this problem is better solved on the client side.
-
-_Client Capability_:
-* property path (optional): `workspace.didChangeWatchedFiles`
-* property type: `DidChangeWatchedFilesClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeWatchedFilesClientCapabilities" name="didChangeWatchedFilesClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface DidChangeWatchedFilesClientCapabilities {
-	/**
-	 * Did change watched files notification supports dynamic registration.
-	 * Please note that the current protocol doesn't support static
-	 * configuration for file changes from the server side.
-	 */
-	dynamicRegistration?: boolean;
-
-	/**
-	 * Whether the client has support for relative patterns
-	 * or not.
-	 *
-	 * @since 3.17.0
-	 */
-	relativePatternSupport?: boolean;
-}
-```
-
-_Registration Options_: `DidChangeWatchedFilesRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeWatchedFilesRegistrationOptions" name="didChangeWatchedFilesRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Describe options to be used when registering for file system change events.
- */
-export interface DidChangeWatchedFilesRegistrationOptions {
-	/**
-	 * The watchers to register.
-	 */
-	watchers: FileSystemWatcher[];
-}
-```
-
-<div class="anchorHolder"><a href="#pattern" name="pattern" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * 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
- */
-export type Pattern = string;
-```
-
-<div class="anchorHolder"><a href="#relativePattern" name="relativePattern" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * A relative pattern is a helper to construct glob patterns that are matched
- * relatively to a base URI. The common value for a `baseUri` is a workspace
- * folder root, but it can be another absolute URI as well.
- *
- * @since 3.17.0
- */
-export interface RelativePattern {
-	/**
-	 * A workspace folder or a base URI to which this pattern will be matched
-	 * against relatively.
-	 */
-	baseUri: WorkspaceFolder | URI;
-
-	/**
-	 * The actual glob pattern;
-	 */
-	pattern: Pattern;
-}
-```
-
-<div class="anchorHolder"><a href="#globPattern" name="globPattern" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The glob pattern. Either a string pattern or a relative pattern.
- *
- * @since 3.17.0
- */
-export type GlobPattern = Pattern | RelativePattern;
-```
-
-<div class="anchorHolder"><a href="#fileSystemWatcher" name="fileSystemWatcher" class="linkableAnchor"></a></div>
-
-```typescript
-export interface FileSystemWatcher {
-	/**
-	 * The glob pattern to watch. See {@link GlobPattern glob pattern}
-	 * for more detail.
-	 *
- 	 * @since 3.17.0 support for relative patterns.
-	 */
-	globPattern: GlobPattern;
-
-	/**
-	 * The kind of events of interest. If omitted it defaults
-	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
-	 * which is 7.
-	 */
-	kind?: WatchKind;
-}
-```
-
-<div class="anchorHolder"><a href="#watchKind" name="watchKind" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace WatchKind {
-	/**
-	 * Interested in create events.
-	 */
-	export const Create = 1;
-
-	/**
-	 * Interested in change events
-	 */
-	export const Change = 2;
-
-	/**
-	 * Interested in delete events
-	 */
-	export const Delete = 4;
-}
-export type WatchKind = uinteger;
-```
-
-_Notification_:
-* method: 'workspace/didChangeWatchedFiles'
-* params: `DidChangeWatchedFilesParams` defined as follows:
-
-<div class="anchorHolder"><a href="#didChangeWatchedFilesParams" name="didChangeWatchedFilesParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface DidChangeWatchedFilesParams {
-	/**
-	 * The actual file events.
-	 */
-	changes: FileEvent[];
-}
-```
-
-Where FileEvents are described as follows:
-
-<div class="anchorHolder"><a href="#fileEvent" name="fileEvent" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * An event describing a file change.
- */
-interface FileEvent {
-	/**
-	 * The file's URI.
-	 */
-	uri: DocumentUri;
-	/**
-	 * The change type.
-	 */
-	type: uinteger;
-}
-```
-
-<div class="anchorHolder"><a href="#fileChangeType" name="fileChangeType" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The file event type.
- */
-export namespace FileChangeType {
-	/**
-	 * The file got created.
-	 */
-	export const Created = 1;
-	/**
-	 * The file got changed.
-	 */
-	export const Changed = 2;
-	/**
-	 * The file got deleted.
-	 */
-	export const Deleted = 3;
-}
-```
-
-#### <a href="#workspace_executeCommand" name="workspace_executeCommand" class="anchor">Execute a command (:leftwards_arrow_with_hook:)</a>
-
-The `workspace/executeCommand` request is sent from the client to the server to trigger command execution on the server. In most cases the server creates a `WorkspaceEdit` structure and applies the changes to the workspace using the request `workspace/applyEdit` which is sent from the server to the client.
-
-_Client Capability_:
-* property path (optional): `workspace.executeCommand`
-* property type: `ExecuteCommandClientCapabilities` defined as follows:
-
-<div class="anchorHolder"><a href="#executeCommandClientCapabilities" name="executeCommandClientCapabilities" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ExecuteCommandClientCapabilities {
-	/**
-	 * Execute command supports dynamic registration.
-	 */
-	dynamicRegistration?: boolean;
-}
-```
-
-_Server Capability_:
-* property path (optional): `executeCommandProvider`
-* property type: `ExecuteCommandOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#executeCommandOptions" name="executeCommandOptions" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ExecuteCommandOptions extends WorkDoneProgressOptions {
-	/**
-	 * The commands to be executed on the server
-	 */
-	commands: string[];
-}
-```
-
-_Registration Options_: `ExecuteCommandRegistrationOptions` defined as follows:
-
-<div class="anchorHolder"><a href="#executeCommandRegistrationOptions" name="executeCommandRegistrationOptions" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Execute command registration options.
- */
-export interface ExecuteCommandRegistrationOptions
-	extends ExecuteCommandOptions {
-}
-```
-
-_Request_:
-* method: 'workspace/executeCommand'
-* params: `ExecuteCommandParams` defined as follows:
-
-<div class="anchorHolder"><a href="#executeCommandParams" name="executeCommandParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ExecuteCommandParams extends WorkDoneProgressParams {
-
-	/**
-	 * The identifier of the actual command handler.
-	 */
-	command: string;
-	/**
-	 * Arguments that the command should be invoked with.
-	 */
-	arguments?: LSPAny[];
-}
-```
-
-The arguments are typically specified when a command is returned from the server to the client. Example requests that return a command are `textDocument/codeAction` or `textDocument/codeLens`.
-
-_Response_:
-* result: `LSPAny` \| `null`
-* error: code and message set in case an exception happens during the request.
-
-#### <a href="#workspace_applyEdit" name="workspace_applyEdit" class="anchor">Applies a WorkspaceEdit (:arrow_right_hook:)</a>
-
-The `workspace/applyEdit` request is sent from the server to the client to modify resource on the client side.
-
-_Client Capability_:
-* property path (optional): `workspace.applyEdit`
-* property type: `boolean`
-
-See also the [WorkspaceEditClientCapabilities](#workspaceEditClientCapabilities) for the supported capabilities of a workspace edit.
-
-_Request_:
-* method: 'workspace/applyEdit'
-* params: `ApplyWorkspaceEditParams` defined as follows:
-
-<div class="anchorHolder"><a href="#applyWorkspaceEditParams" name="applyWorkspaceEditParams" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ApplyWorkspaceEditParams {
-	/**
-	 * An optional label of the workspace edit. This label is
-	 * presented in the user interface for example on an undo
-	 * stack to undo the workspace edit.
-	 */
-	label?: string;
-
-	/**
-	 * The edits to apply.
-	 */
-	edit: WorkspaceEdit;
-}
-```
-
-_Response_:
-* result: `ApplyWorkspaceEditResult` defined as follows:
-
-<div class="anchorHolder"><a href="#applyWorkspaceEditResult" name="applyWorkspaceEditResult" class="linkableAnchor"></a></div>
-
-```typescript
-export interface ApplyWorkspaceEditResult {
-	/**
-	 * Indicates whether the edit was applied or not.
-	 */
-	applied: boolean;
-
-	/**
-	 * An optional textual description for why the edit was not applied.
-	 * This may be used by the server for diagnostic logging or to provide
-	 * a suitable error for a request that triggered the edit.
-	 */
-	failureReason?: string;
-
-	/**
-	 * Depending on the client's failure handling strategy `failedChange`
-	 * might contain the index of the change that failed. This property is
-	 * only available if the client signals a `failureHandling` strategy
-	 * in its client capabilities.
-	 */
-	failedChange?: uinteger;
-}
-```
-* error: code and message set in case an exception happens during the request.
-
-
-### <a href="#windowFeatures" name="windowFeatures" class="anchor">Window Features</a>
-
-#### <a href="#window_showMessage" name="window_showMessage" class="anchor">ShowMessage Notification (:arrow_left:)</a>
-
-The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
-
-_Notification_:
-* method: 'window/showMessage'
-* params: `ShowMessageParams` defined as follows:
-
-```typescript
-interface ShowMessageParams {
-	/**
-	 * The message type. See {@link MessageType}.
-	 */
-	type: MessageType;
-
-	/**
-	 * The actual message.
-	 */
-	message: string;
-}
-```
-
-Where the type is defined as follows:
-
-<div class="anchorHolder"><a href="#messageType" name="messageType" class="linkableAnchor"></a></div>
-
-```typescript
-export namespace MessageType {
-	/**
-	 * An error message.
-	 */
-	export const Error = 1;
-	/**
-	 * A warning message.
-	 */
-	export const Warning = 2;
-	/**
-	 * An information message.
-	 */
-	export const Info = 3;
-	/**
-	 * A log message.
-	 */
-	export const Log = 4;
-}
-
-export type MessageType = 1 | 2 | 3 | 4;
-```
-
-#### <a href="#window_showMessageRequest" name="window_showMessageRequest" class="anchor">ShowMessage Request (:arrow_right_hook:)</a>
-
-The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client.
-
-_Client Capability_:
-* property path (optional): `window.showMessage`
-* property type: `ShowMessageRequestClientCapabilities` defined as follows:
-
-```typescript
-/**
- * Show message request client capabilities
- */
-export interface ShowMessageRequestClientCapabilities {
-	/**
-	 * Capabilities specific to the `MessageActionItem` type.
-	 */
-	messageActionItem?: {
-		/**
-		 * Whether the client supports additional attributes which
-		 * are preserved and sent back to the server in the
-		 * request's response.
-		 */
-		additionalPropertiesSupport?: boolean;
-	};
-}
-```
-
-_Request_:
-* method: 'window/showMessageRequest'
-* params: `ShowMessageRequestParams` defined as follows:
-
-<div class="anchorHolder"><a href="#showMessageRequestParams" name="showMessageRequestParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface ShowMessageRequestParams {
-	/**
-	 * The message type. See {@link MessageType}
-	 */
-	type: MessageType;
-
-	/**
-	 * The actual message
-	 */
-	message: string;
-
-	/**
-	 * The message action items to present.
-	 */
-	actions?: MessageActionItem[];
-}
-```
-
-Where the `MessageActionItem` is defined as follows:
-
-<div class="anchorHolder"><a href="#messageActionItem" name="messageActionItem" class="linkableAnchor"></a></div>
-
-```typescript
-interface MessageActionItem {
-	/**
-	 * A short title like 'Retry', 'Open Log' etc.
-	 */
-	title: string;
-}
-```
-
-_Response_:
-* result: the selected `MessageActionItem` \| `null` if none got selected.
-* error: code and message set in case an exception happens during showing a message.
-
-#### <a href="#window_showDocument" name="window_showDocument" class="anchor">Show Document Request (:arrow_right_hook:)</a>
-
-> New in version 3.16.0
-
-The show document request is sent from a server to a client to ask the client to display a particular document in the user interface.
-
-_Client Capability_:
-* property path (optional): `window.showDocument`
-* property type: `ShowDocumentClientCapabilities` defined as follows:
-
-```typescript
-/**
- * Client capabilities for the show document request.
- *
- * @since 3.16.0
- */
-export interface ShowDocumentClientCapabilities {
-	/**
-	 * The client has support for the show document
-	 * request.
-	 */
-	support: boolean;
-}
-```
-
-_Request_:
-* method: 'window/showDocument'
-* params: `ShowDocumentParams` defined as follows:
-
-<div class="anchorHolder"><a href="#showDocumentParams" name="showDocumentParams" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * Params to show a document.
- *
- * @since 3.16.0
- */
-export interface ShowDocumentParams {
-	/**
-	 * The document uri to show.
-	 */
-	uri: URI;
-
-	/**
-	 * Indicates to show the resource in an external program.
-	 * To show for example `https://code.visualstudio.com/`
-	 * in the default WEB browser set `external` to `true`.
-	 */
-	external?: boolean;
-
-	/**
-	 * An optional property to indicate whether the editor
-	 * showing the document should take focus or not.
-	 * Clients might ignore this property if an external
-	 * program is started.
-	 */
-	takeFocus?: boolean;
-
-	/**
-	 * An optional selection range if the document is a text
-	 * document. Clients might ignore the property if an
-	 * external program is started or the file is not a text
-	 * file.
-	 */
-	selection?: Range;
-}
-```
-
-_Response_:
-
-* result: `ShowDocumentResult` defined as follows:
-
-<div class="anchorHolder"><a href="#showDocumentResult" name="showDocumentResult" class="linkableAnchor"></a></div>
-
-```typescript
-/**
- * The result of an show document request.
- *
- * @since 3.16.0
- */
-export interface ShowDocumentResult {
-	/**
-	 * A boolean indicating if the show was successful.
-	 */
-	success: boolean;
-}
-```
-* error: code and message set in case an exception happens during showing a document.
-
-#### <a href="#window_logMessage" name="window_logMessage" class="anchor">LogMessage Notification (:arrow_left:)</a>
-
-The log message notification is sent from the server to the client to ask the client to log a particular message.
-
-_Notification_:
-* method: 'window/logMessage'
-* params: `LogMessageParams` defined as follows:
-
-<div class="anchorHolder"><a href="#logMessageParams" name="logMessageParams" class="linkableAnchor"></a></div>
-
-```typescript
-interface LogMessageParams {
-	/**
-	 * The message type. See {@link MessageType}
-	 */
-	type: MessageType;
-
-	/**
-	 * The actual message
-	 */
-	message: string;
-}
-```
-
-#### <a href="#window_workDoneProgress_create" name="window_workDoneProgress_create" class="anchor"> Create Work Done Progress (:arrow_right_hook:)</a>
-
-The `window/workDoneProgress/create` request is sent from the server to the client to ask the client to create a work done progress.
-
-_Client Capability_:
-* property name (optional): `window.workDoneProgress`
-* property type: `boolean`
-
-_Request_:
-
-* method: 'window/workDoneProgress/create'
-* params: `WorkDoneProgressCreateParams` defined as follows:
-
-```typescript
-export interface WorkDoneProgressCreateParams {
-	/**
-	 * The token to be used to report progress.
-	 */
-	token: ProgressToken;
-}
-```
-
-_Response_:
-
-* result: void
-* error: code and message set in case an exception happens during the 'window/workDoneProgress/create' request. In case an error occurs a server must not send any progress notification using the token provided in the `WorkDoneProgressCreateParams`.
-
-#### <a href="#window_workDoneProgress_cancel" name="window_workDoneProgress_cancel" class="anchor"> Cancel a Work Done Progress (:arrow_right:)</a>
-
-The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`. The progress need not be marked as `cancellable` to be cancelled and a client may cancel a progress for any number of reasons: in case of error, reloading a workspace etc.
-
-_Notification_:
-
-* method: 'window/workDoneProgress/cancel'
-* params: `WorkDoneProgressCancelParams` defined as follows:
-
-```typescript
-export interface WorkDoneProgressCancelParams {
-	/**
-	 * The token to be used to report progress.
-	 */
-	token: ProgressToken;
-}
-```
-#### <a href="#telemetry_event" name="telemetry_event" class="anchor">Telemetry Notification (:arrow_left:)</a>
-
-The telemetry notification is sent from the server to the client to ask the client to log a telemetry event. The protocol doesn't specify the payload since no interpretation of the data happens in the protocol. Most clients even don't handle the event directly but forward them to the extensions owing the corresponding server issuing the event.
-
-_Notification_:
-* method: 'telemetry/event'
-* params: 'object' \| 'number' \| 'boolean' \| 'string';
-
-
-#### <a href="#miscellaneous" name="miscellaneous" class="anchor">Miscellaneous</a>
-
-#### <a href="#implementationConsiderations" name="implementationConsiderations" class="anchor">Implementation Considerations</a>
-
-Language servers usually run in a separate process and client communicate with them in an asynchronous fashion. Additionally clients usually allow users to interact with the source code even if request results are pending. We recommend the following implementation pattern to avoid that clients apply outdated response results:
-
-- if a client sends a request to the server and the client state changes in a way that it invalidates the response it should do the following:
-  - cancel the server request and ignore the result if the result is not useful for the client anymore. If necessary the client should resend the request.
-  - keep the request running if the client can still make use of the result by for example transforming it to a new result by applying the state change to the result.
-- servers should therefore not decide by themselves to cancel requests simply due to that fact that a state change notification is detected in the queue. As said the result could still be useful for the client.
-- if a server detects an internal state change (for example a project context changed) that invalidates the result of a request in execution the server can error these requests with `ContentModified`. If clients receive a `ContentModified` error, it generally should not show it in the UI for the end-user. Clients can resend the request if they know how to do so. It should be noted that for all position based requests it might be especially hard for clients to re-craft a request.
-- if a client notices that a server exits unexpectedly, it should try to restart the server. However clients should be careful not to restart a crashing server endlessly. VS Code, for example, doesn't restart a server which has crashed 5 times in the last 180 seconds.
-
-Servers usually support different communication channels (e.g. stdio, pipes, ...). To ease the usage of servers in different clients it is highly recommended that a server implementation supports the following command line arguments to pick the communication channel:
-
-- **stdio**: uses stdio as the communication channel.
-- **pipe**: use pipes (Windows) or socket files (Linux, Mac) as the communication channel. The pipe / socket file name is passed as the next arg or with `--pipe=`.
-- **socket**: uses a socket as the communication channel. The port is passed as next arg or with `--port=`.
-- **node-ipc**: use node IPC communication between the client and the server. This is only support if both client and server run under node.
-
-To support the case that the editor starting a server crashes an editor should also pass its process id to the server. This allows the server to monitor the editor process and to shutdown itself if the editor process dies. The process id pass on the command line should be the same as the one passed in the initialize parameters. The command line argument to use is `--clientProcessId`.
-
-#### <a href="#metaModel" name="metaModel" class="anchor">Meta Model</a>
-
-Since 3.17 there is a meta model describing the LSP protocol:
-
-- [metaModel.json](../metaModel/metaModel.json): The actual meta model for the LSP 3.17 specification
-- [metaModel.ts](../metaModel/metaModel.ts): A TypeScript file defining the data types that make up the meta model.
-- [metaModel.schema.json](../metaModel/metaModel.schema.json): A JSON schema file defining the data types that make up the meta model. Can be used to generate code to read the meta model JSON file.
-
-### <a href="#changeLog" name="changeLog" class="anchor">Change Log</a>
-
-#### <a href="#version_3_17_0" name="version_3_17_0" class="anchor">3.17.0 (05/10/2022)</a>
-
-* Specify how clients will handle stale requests.
-* Add support for a completion item label details.
-* Add support for workspace symbol resolve request.
-* Add support for label details and insert text mode on completion items.
-* Add support for shared values on CompletionItemList.
-* Add support for HTML tags in Markdown.
-* Add support for collapsed text in folding.
-* Add support for trigger kinds on code action requests.
-* Add the following support to semantic tokens:
-  - server cancelable
-  - augmentation of syntax tokens
-* Add support to negotiate the position encoding.
-* Add support for HTML tags in markdown.
-* Add support for relative patterns in file watchers.
-* Add support for type hierarchies
-* Add support for inline values.
-* Add support for inlay hints.
-* Add support for notebook documents.
-* Add support for diagnostic pull model.
-
-#### <a href="#version_3_16_0" name="version_3_16_0" class="anchor">3.16.0 (12/14/2020)</a>
-
-* Add support for tracing.
-* Add semantic token support.
-* Add call hierarchy support.
-* Add client capability for resolving text edits on completion items.
-* Add support for client default behavior on renames.
-* Add support for insert and replace ranges on `CompletionItem`.
-* Add support for diagnostic code descriptions.
-* Add support for document symbol provider label.
-* Add support for tags on `SymbolInformation` and `DocumentSymbol`.
-* Add support for moniker request method.
-* Add support for code action `data` property.
-* Add support for code action `disabled` property.
-* Add support for code action resolve request.
-* Add support for diagnostic `data` property.
-* Add support for signature information `activeParameter` property.
-* Add support for `workspace/didCreateFiles` notifications and `workspace/willCreateFiles` requests.
-* Add support for `workspace/didRenameFiles` notifications and `workspace/willRenameFiles` requests.
-* Add support for `workspace/didDeleteFiles` notifications and `workspace/willDeleteFiles` requests.
-* Add client capability to signal whether the client normalizes line endings.
-* Add support to preserve additional attributes on `MessageActionItem`.
-* Add support to provide the clients locale in the initialize call.
-* Add support for opening and showing a document in the client user interface.
-* Add support for linked editing.
-* Add support for change annotations in text edits as well as in create file, rename file and delete file operations.
-
-#### <a href="#version_3_15_0" name="version_3_15_0" class="anchor">3.15.0 (01/14/2020)</a>
-
-* Add generic progress reporting support.
-* Add specific work done progress reporting support to requests where applicable.
-* Add specific partial result progress support to requests where applicable.
-* Add support for `textDocument/selectionRange`.
-* Add support for server and client information.
-* Add signature help context.
-* Add Erlang and Elixir to the list of supported programming languages
-* Add `version` on `PublishDiagnosticsParams`
-* Add `CodeAction#isPreferred` support.
-* Add `CompletionItem#tag` support.
-* Add `Diagnostic#tag` support.
-* Add `DocumentLink#tooltip` support.
-* Add `trimTrailingWhitespace`, `insertFinalNewline` and `trimFinalNewlines` to `FormattingOptions`.
-* Clarified `WorkspaceSymbolParams#query` parameter.
-
-
-#### <a href="#version_3_14_0" name="version_3_14_0" class="anchor">3.14.0 (12/13/2018)</a>
-
-* Add support for signature label offsets.
-* Add support for location links.
-* Add support for `textDocument/declaration` request.
-
-#### <a href="#version_3_13_0" name="version_3_13_0" class="anchor">3.13.0 (9/11/2018)</a>
-
-* Add support for file and folder operations (create, rename, move) to workspace edits.
-
-#### <a href="#version_3_12_0" name="version_3_12_0" class="anchor">3.12.0 (8/23/2018)</a>
-
-* Add support for `textDocument/prepareRename` request.
-
-#### <a href="#version_3_11_0" name="version_3_11_0" class="anchor">3.11.0 (8/21/2018)</a>
-
-* Add support for CodeActionOptions to allow a server to provide a list of code action it supports.
-
-#### <a href="#version_3_10_0" name="version_3_10_0" class="anchor">3.10.0 (7/23/2018)</a>
-
-* Add support for hierarchical document symbols as a valid response to a `textDocument/documentSymbol` request.
-* Add support for folding ranges as a valid response to a `textDocument/foldingRange` request.
-
-#### <a href="#version_3_9_0" name="version_3_9_0" class="anchor">3.9.0 (7/10/2018)</a>
-
-* Add support for `preselect` property in `CompletionItem`
-
-#### <a href="#version_3_8_0" name="version_3_8_0" class="anchor">3.8.0 (6/11/2018)</a>
-
-* Added support for CodeAction literals to the `textDocument/codeAction` request.
-* ColorServerCapabilities.colorProvider can also be a boolean
-* Corrected ColorPresentationParams.colorInfo to color (as in the `d.ts` and in implementations)
-
-#### <a href="#version_3_7_0" name="version_3_7_0" class="anchor">3.7.0 (4/5/2018)</a>
-
-* Added support for related information to Diagnostics.
-
-#### <a href="#version_3_6_0" name="version_3_6_0" class="anchor">3.6.0 (2/22/2018)</a>
-
-Merge the proposed protocol for workspace folders, configuration, go to type definition, go to implementation and document color provider into the main branch of the specification. For details see:
-
-* [Get Workspace Folders](https://microsoft.github.io/language-server-protocol/specification#workspace_workspaceFolders)
-* [DidChangeWorkspaceFolders Notification](https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeWorkspaceFolders)
-* [Get Configuration](https://microsoft.github.io/language-server-protocol/specification#workspace_configuration)
-* [Go to Type Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_typeDefinition)
-* [Go to Implementation](https://microsoft.github.io/language-server-protocol/specification#textDocument_implementation)
-* [Document Color](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentColor)
-* [Color Presentation](https://microsoft.github.io/language-server-protocol/specification#textDocument_colorPresentation)
-
-In addition we enhanced the `CompletionTriggerKind` with a new value `TriggerForIncompleteCompletions: 3 = 3` to signal the a completion request got trigger since the last result was incomplete.
-
-#### <a href="#version_3_5_0" name="version_3_5_0" class="anchor">3.5.0</a>
-
-Decided to skip this version to bring the protocol version number in sync the with npm module vscode-languageserver-protocol.
-
-#### <a href="#version_3_4_0" name="version_3_4_0" class="anchor">3.4.0 (11/27/2017)</a>
-
-* [extensible completion item and symbol kinds](https://github.com/Microsoft/language-server-protocol/issues/129)
-
-#### <a href="version_3_3_0" name="version_3_3_0" class="anchor">3.3.0 (11/24/2017)</a>
-
-* Added support for `CompletionContext`
-* Added support for `MarkupContent`
-* Removed old New and Updated markers.
-
-#### <a href="version_3_2_0" name="version_3_2_0" class="anchor">3.2.0 (09/26/2017)</a>
-
-* Added optional `commitCharacters` property to the `CompletionItem`
-
-#### <a href="version_3_1_0" name="version_3_1_0" class="anchor">3.1.0 (02/28/2017)</a>
-
-* Make the `WorkspaceEdit` changes backwards compatible.
-* Updated the specification to correctly describe the breaking changes from 2.x to 3.x around `WorkspaceEdit`and `TextDocumentEdit`.
-
-#### <a href="#version_3_0_0" name="version_3_0_0" class="anchor">3.0 Version</a>
-
-- add support for client feature flags to support that servers can adapt to different client capabilities. An example is the new `textDocument/willSaveWaitUntil` request which not all clients might be able to support. If the feature is disabled in the client capabilities sent on the initialize request, the server can't rely on receiving the request.
-- add support to experiment with new features. The new `ClientCapabilities.experimental` section together with feature flags allow servers to provide experimental feature without the need of ALL clients to adopt them immediately.
-- servers can more dynamically react to client features. Capabilities can now be registered and unregistered after the initialize request using the new `client/registerCapability` and `client/unregisterCapability`. This for example allows servers to react to settings or configuration changes without a restart.
-- add support for `textDocument/willSave` notification and `textDocument/willSaveWaitUntil` request.
-- add support for `textDocument/documentLink` request.
-- add a `rootUri` property to the initializeParams in favor of the `rootPath` property.
diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart
deleted file mode 100644
index 2a245f0..0000000
--- a/pkg/analysis_server/tool/lsp_spec/markdown.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2018, 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.
-
-final _methodNamesPattern =
-    RegExp(r'''\* method: ['`](.*?)[`'][,.]?\r?\n''', multiLine: true);
-final _typeScriptBlockPattern =
-    RegExp(r'\B```typescript([\S\s]*?)\n\s*```', multiLine: true);
-
-List<String> extractMethodNames(String spec) {
-  return _methodNamesPattern
-      .allMatches(spec)
-      .map((m) => m.group(1)!.trim())
-      .toList();
-}
-
-/// Extracts fenced code blocks that are explicitly marked as TypeScript from a
-/// markdown document.
-List<String> extractTypeScriptBlocks(String text) {
-  return _typeScriptBlockPattern
-      .allMatches(text)
-      .map((m) => m.group(1)!.trim())
-      .toList();
-}
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model.dart b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
new file mode 100644
index 0000000..5f8d860
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
@@ -0,0 +1,318 @@
+// Copyright (c) 2018, 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 'package:collection/collection.dart';
+
+import 'codegen_dart.dart';
+
+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';
+
+bool isUndefinedType(TypeBase t) => t is TypeReference && t.name == 'undefined';
+
+class ArrayType extends TypeBase {
+  final TypeBase elementType;
+
+  ArrayType(this.elementType);
+
+  @override
+  String get dartType => 'List';
+  @override
+  String get typeArgsString => '<${elementType.dartTypeWithTypeArgs}>';
+}
+
+/// A constant value parsed from the LSP JSON model.
+///
+/// Used for well-known values in the spec, such as request Method names and
+/// error codes.
+class Constant extends Member with LiteralValueMixin {
+  TypeBase type;
+  String value;
+  Constant({
+    required super.name,
+    super.comment,
+    required this.type,
+    required this.value,
+  });
+
+  String get valueAsLiteral => _asLiteral(value);
+}
+
+/// A field parsed from the LSP JSON model.
+class Field extends Member {
+  final TypeBase type;
+  final bool allowsNull;
+  final bool allowsUndefined;
+  Field({
+    required super.name,
+    super.comment,
+    required this.type,
+    required this.allowsNull,
+    required this.allowsUndefined,
+  });
+}
+
+class FixedValueField extends Field {
+  final String value;
+  FixedValueField({
+    required super.name,
+    super.comment,
+    required this.value,
+    required super.type,
+    required super.allowsNull,
+    required super.allowsUndefined,
+  });
+}
+
+/// An interface/class parsed from the LSP JSON model.
+class Interface extends LspEntity {
+  final List<String> typeArgs;
+  final List<TypeReference> baseTypes;
+  final List<Member> members;
+
+  Interface({
+    required super.name,
+    super.comment,
+    this.typeArgs = const [],
+    this.baseTypes = const [],
+    required this.members,
+  }) {
+    baseTypes.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
+    members.sortBy((member) => member.name.toLowerCase());
+  }
+
+  Interface.inline(String name, List<Member> members)
+      : this(name: name, members: members);
+
+  String get nameWithTypeArgs => '$name$typeArgsString';
+
+  String get typeArgsString =>
+      typeArgs.isNotEmpty ? '<${typeArgs.join(', ')}>' : '';
+}
+
+/// A type parsed from the LSP JSON model that has a singe literal value.
+class LiteralType extends TypeBase with LiteralValueMixin {
+  final TypeBase type;
+  final String _literal;
+
+  LiteralType(this.type, this._literal);
+
+  @override
+  String get dartType => type.dartType;
+
+  @override
+  String get typeArgsString => type.typeArgsString;
+
+  @override
+  String get uniqueTypeIdentifier => '$_literal:${super.uniqueTypeIdentifier}';
+
+  String get valueAsLiteral => _asLiteral(_literal);
+}
+
+/// A special class of Union types where the values are all literals of the same
+/// type.
+///
+/// This allows the Dart field for this type to be the the common base type
+/// rather than an EitherX<>.
+class LiteralUnionType extends UnionType {
+  final List<LiteralType> literalTypes;
+
+  LiteralUnionType(this.literalTypes) : super(literalTypes);
+
+  @override
+  String get dartType => types.first.dartType;
+
+  @override
+  String get typeArgsString => types.first.typeArgsString;
+}
+
+mixin LiteralValueMixin {
+  /// Returns [value] as the literal Dart code required to represent this value.
+  String _asLiteral(String value) {
+    if (num.tryParse(value) == null) {
+      // Add quotes around strings.
+      final prefix = value.contains(r'$') ? 'r' : '';
+      return "$prefix'$value'";
+    } else {
+      return value;
+    }
+  }
+}
+
+/// Base class for named entities (both classes/interfaces and members) parsed
+/// from the LSP JSON model.
+abstract class LspEntity {
+  final String name;
+  final String? comment;
+  final bool isDeprecated;
+  LspEntity({
+    required this.name,
+    required this.comment,
+  }) : isDeprecated = comment?.contains('@deprecated') ?? false;
+}
+
+/// An enum parsed from the LSP JSON model.
+class LspEnum extends LspEntity {
+  final TypeBase typeOfValues;
+  final List<Member> members;
+  LspEnum({
+    required super.name,
+    super.comment,
+    required this.typeOfValues,
+    required this.members,
+  }) {
+    members.sortBy((member) => member.name.toLowerCase());
+  }
+}
+
+class LspMetaModel {
+  final List<LspEntity> types;
+
+  LspMetaModel(this.types);
+}
+
+/// A [Map] type parsed from the LSP JSON model.
+class MapType extends TypeBase {
+  final TypeBase indexType;
+  final TypeBase valueType;
+
+  MapType(this.indexType, this.valueType);
+
+  @override
+  String get dartType => 'Map';
+
+  @override
+  String get typeArgsString =>
+      '<${indexType.dartTypeWithTypeArgs}, ${valueType.dartTypeWithTypeArgs}>';
+}
+
+/// Base class for members ([Constant] and [Fields]s) parsed from the LSP JSON
+/// model.
+abstract class Member extends LspEntity {
+  Member({
+    required super.name,
+    super.comment,
+  });
+}
+
+class TypeAlias extends LspEntity {
+  final TypeBase baseType;
+  TypeAlias({
+    required super.name,
+    super.comment,
+    required this.baseType,
+  });
+}
+
+/// Base class for a Type parsed from the LSP JSON model.
+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
+  /// (for example two types that resolve to "Object?" in Dart).
+  String get uniqueTypeIdentifier => dartTypeWithTypeArgs;
+}
+
+/// 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');
+  final String name;
+  final List<TypeBase> typeArgs;
+
+  TypeReference(this.name, {this.typeArgs = const []}) {
+    if (name == 'Array' || name.endsWith('[]')) {
+      throw 'Type should not be used for arrays, use ArrayType instead';
+    }
+  }
+
+  @override
+  String get dartType {
+    // Always resolve type aliases when asked for our Dart type.
+    final resolvedType = resolveTypeAlias(this);
+    if (resolvedType != this) {
+      return resolvedType.dartType;
+    }
+
+    const mapping = <String, String>{
+      'boolean': 'bool',
+      'string': 'String',
+      'number': 'num',
+      'integer': 'int',
+      // 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
+      'MarkedString': 'String'
+    };
+
+    final typeName = mapping[name] ?? name;
+    return typeName;
+  }
+
+  @override
+  String get typeArgsString {
+    // Always resolve type aliases when asked for our Dart type.
+    final resolvedType = resolveTypeAlias(this);
+    if (resolvedType != this) {
+      return resolvedType.typeArgsString;
+    }
+
+    return typeArgs.isNotEmpty
+        ? '<${typeArgs.map((t) => t.dartTypeWithTypeArgs).join(', ')}>'
+        : '';
+  }
+}
+
+/// A union type parsed from the LSP JSON model.
+///
+/// Union types will be represented in Dart using a custom `EitherX<A, B, ...>`
+/// class.
+class UnionType extends TypeBase {
+  final List<TypeBase> types;
+
+  UnionType(this.types) {
+    // Ensure types are always sorted alphabetically to simplify sharing code
+    // because `Either2<A, B>` and `Either2<B, A>` are not the same.
+    types.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
+  }
+
+  UnionType.nullable(TypeBase type) : this([type, TypeReference.Null_]);
+
+  @override
+  String get dartType {
+    if (types.length > 4) {
+      throw 'Unions of more than 4 types are not supported.';
+    }
+    return 'Either${types.length}';
+  }
+
+  @override
+  String get typeArgsString {
+    final typeArgs = types.map((t) => t.dartTypeWithTypeArgs).join(', ');
+    return '<$typeArgs>';
+  }
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
new file mode 100644
index 0000000..e28c919
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
@@ -0,0 +1,384 @@
+// 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.
+
+import 'meta_model.dart';
+
+/// Helper methods to clean the meta model to produce better Dart classes.
+///
+/// Cleaning includes:
+///
+/// - Unwrapping comments that have been wrapped in the source model
+/// - Removing relative hyperlinks from comments that assume rendering in an
+///     HTML page with anchors
+/// - Merging types that are distinct in the meta model but we want as one
+/// - Removing types in the spec that we will never use
+/// - Renaming types that may have long or sub-optimal generated names
+/// - Simplifying union types that contain duplicates/overlaps
+class LspMetaModelCleaner {
+  /// A pattern to match newlines in source comments that are likely for
+  /// wrapping and not formatting. This allows us to rewrap based on our indent
+  /// level/line length without potentially introducing very short lines.
+  final _sourceCommentWrappingNewlinesPattern =
+      RegExp(r'[\w`\]\).]\n[\w`\[\(]');
+  final _sourceCommentDocumentLinksPattern =
+      RegExp(r'\[([`\w \-.]+)\] ?\((#[^)]+)\)');
+
+  /// Cleans an entire [LspMetaModel].
+  LspMetaModel cleanModel(LspMetaModel model) {
+    final types = cleanTypes(model.types);
+    return LspMetaModel(types);
+  }
+
+  /// Cleans a List of types.
+  List<LspEntity> cleanTypes(List<LspEntity> types) {
+    types = _mergeTypes(types);
+    types = types
+        .where((type) => _includeTypeInOutput(type.name))
+        .map(_clean)
+        .toList();
+    types = _renameTypes(types).toList();
+    return types;
+  }
+
+  /// Whether a type should be retained type signatures in generated code.
+  bool _allowTypeInUnions(TypeBase type) {
+    // Don't allow arrays of MarkedStrings, but do allow simple MarkedStrings.
+    // The only place that uses these are Hovers and we only send one value
+    // (to match the MarkupString equiv) so the array just makes the types
+    // unnecessarily complicated.
+    if (type is ArrayType) {
+      // TODO(dantup): Consider removing this, it's not adding much.
+      final elementType = type.elementType;
+      if (elementType is TypeReference && elementType.name == 'MarkedString') {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Cleans a single [LspEntity].
+  LspEntity _clean(LspEntity type) {
+    if (type is Interface) {
+      return _cleanInterface(type);
+    } else if (type is LspEnum) {
+      return _cleanNamespace(type);
+    } else if (type is TypeAlias) {
+      return _cleanTypeAlias(type);
+    } else {
+      throw 'Cleaning $type is not implemented.';
+    }
+  }
+
+  String? _cleanComment(String? text) {
+    if (text == null) {
+      return text;
+    }
+
+    // Unwrap any wrapping in the source by replacing any matching newlines with
+    // spaces.
+    text = text.replaceAllMapped(
+      _sourceCommentWrappingNewlinesPattern,
+      (match) => match.group(0)!.replaceAll('\n', ' '),
+    );
+
+    // Strip any relative links that are intended for displaying online in the
+    // HTML spec.
+    text = text.replaceAllMapped(
+      _sourceCommentDocumentLinksPattern,
+      (match) => match.group(1)!,
+    );
+
+    return text;
+  }
+
+  Constant _cleanConst(Constant const_) {
+    return Constant(
+      name: const_.name,
+      comment: _cleanComment(const_.comment),
+      type: _cleanType(const_.type),
+      value: const_.value,
+    );
+  }
+
+  Field _cleanField(String parentName, Field field) {
+    final improvedType = _getImprovedType(parentName, field.name);
+    final type = improvedType ?? field.type;
+
+    return Field(
+      name: field.name,
+      comment: _cleanComment(field.comment),
+      type: _cleanType(type),
+      allowsNull: field.allowsNull,
+      allowsUndefined: field.allowsUndefined,
+    );
+  }
+
+  Interface _cleanInterface(Interface interface) {
+    return Interface(
+      name: interface.name,
+      comment: _cleanComment(interface.comment),
+      typeArgs: interface.typeArgs,
+      baseTypes: interface.baseTypes
+          .where((type) => _includeTypeInOutput(type.name))
+          .toList(),
+      members: interface.members
+          .map((member) => _cleanMember(interface.name, member))
+          .toList(),
+    );
+  }
+
+  Member _cleanMember(String parentName, Member member) {
+    if (member is Field) {
+      return _cleanField(parentName, member);
+    } else if (member is Constant) {
+      return _cleanConst(member);
+    } else {
+      throw 'Cleaning $member is not implemented.';
+    }
+  }
+
+  LspEnum _cleanNamespace(LspEnum namespace) {
+    return LspEnum(
+      name: namespace.name,
+      comment: _cleanComment(namespace.comment),
+      typeOfValues: namespace.typeOfValues,
+      members: namespace.members
+          .map((member) => _cleanMember(namespace.name, member))
+          .toList(),
+    );
+  }
+
+  TypeBase _cleanType(TypeBase type) {
+    if (type is UnionType) {
+      return _cleanUnionType(type);
+    } else if (type is ArrayType) {
+      return ArrayType(_cleanType(type.elementType));
+    } else {
+      return type;
+    }
+  }
+
+  TypeAlias _cleanTypeAlias(TypeAlias typeAlias) {
+    return TypeAlias(
+      name: typeAlias.name,
+      comment: _cleanComment(typeAlias.comment),
+      baseType: typeAlias.baseType,
+    );
+  }
+
+  /// Removes any duplicate types in a union.
+  ///
+  /// For example, if we map multiple types into `Object?` we don't want to end
+  /// up with `Either2<Object?, Object?>`.
+  ///
+  /// Key on `dartType` to ensure we combine different types that will map down
+  /// to the same type.
+  TypeBase _cleanUnionType(UnionType type) {
+    var uniqueTypes = Map.fromEntries(
+      type.types
+          .where(_allowTypeInUnions)
+          .map((t) => MapEntry(t.uniqueTypeIdentifier, t)),
+    ).values.toList();
+
+    // If our list includes something that maps to Object? as well as other
+    // 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);
+    }
+
+    // Finally, sort the types by name so that we always generate the same type
+    // for the same combination to improve reuse of helper methods used in
+    // multiple handlers.
+    uniqueTypes.sort((t1, t2) => t1.dartType.compareTo(t2.dartType));
+
+    // 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);
+  }
+
+  /// Improves types in code generated from the LSP model, including:
+  ///
+  /// - Making some untyped fields (like `CompletionItem.data`) strong typed for
+  ///   our use.
+  ///
+  /// - Simplifying unions for types generated only by the server to avoid a lot
+  ///   of wrapping in `EitherX<Y,Z>.tX()`.
+  TypeBase? _getImprovedType(String interfaceName, String? fieldName) {
+    const improvedTypeMappings = <String, Map<String, String>>{
+      'Diagnostic': {
+        'code': 'String',
+      },
+      'CompletionItem': {
+        'data': 'CompletionItemResolutionInfo',
+      },
+      'ParameterInformation': {
+        'label': 'String',
+      },
+      'TextDocumentEdit': {
+        'edits': 'TextDocumentEditEdits',
+      }
+    };
+
+    final interface = improvedTypeMappings[interfaceName];
+
+    final improvedTypeName = interface != null ? interface[fieldName] : null;
+
+    return improvedTypeName != null
+        ? improvedTypeName.endsWith('[]')
+            ? ArrayType(TypeReference(
+                improvedTypeName.substring(0, improvedTypeName.length - 2)))
+            : improvedTypeName.endsWith('?')
+                ? UnionType.nullable(TypeReference(
+                    improvedTypeName.substring(0, improvedTypeName.length - 1)))
+                : TypeReference(improvedTypeName)
+        : null;
+  }
+
+  /// Some types are merged together. This method returns the type that [name]s
+  /// members should be merged into.
+  String? _getMergeTarget(String name) {
+    switch (name) {
+      // The meta model defines both `LSPErrorCodes` and `ErrorCodes`. The
+      // intention was that one is JSONRPC and one is LSP codes, but some codes
+      // were defined in the wrong enum with the wrong values, but kept for
+      // backwards compatibility. For simplicity, we merge them all into `ErrorCodes`.
+      case 'LSPErrorCodes':
+        return 'ErrorCodes';
+      // In the model, `InitializeParams` is defined as by two classes,
+      // `_InitializeParams` and `WorkspaceFoldersInitializeParams`. This
+      // split doesn't add anything but makes the types less clear so we
+      // merge them into `InitializeParams`.
+      case '_InitializeParams':
+        return 'InitializeParams';
+      case 'WorkspaceFoldersInitializeParams':
+        return 'InitializeParams';
+      default:
+        return null;
+    }
+  }
+
+  /// Removes types that are in the spec that we don't want to emit.
+  bool _includeTypeInOutput(String name) {
+    const ignoredTypes = {
+      // InitializeError is not used for v3.0 (Feb 2017) and by dropping it we
+      // don't have to handle any cases where both a namespace and interfaces
+      // are declared with the same name.
+      'InitializeError',
+      // Merged into InitializeParams.
+      '_InitializeParams',
+      'WorkspaceFoldersInitializeParams',
+      // We don't use these clases and they weren't in the TS version of the
+      // spec so continue to not generate them until required.
+      'DidChangeConfigurationRegistrationOptions',
+      // LSPAny/LSPObject are used by the LSP spec for unions of basic types.
+      // We map these onto Object? and don't use this type (and don't support
+      // unions with so many types).
+      'LSPAny',
+      'LSPObject',
+      // The meta model currently includes an unwanted type named 'T' that we
+      // don't want to create a class for.
+      // TODO(dantup): Remove this once it's gone from the JSON model.
+      'T',
+    };
+    const ignoredPrefixes = {
+      // We don't emit MarkedString because it gets mapped to a simple String
+      // when getting the .dartType for it.
+      'MarkedString'
+    };
+    final shouldIgnore = ignoredTypes.contains(name) ||
+        ignoredPrefixes.any((ignore) => name.startsWith(ignore));
+    return !shouldIgnore;
+  }
+
+  LspEntity _merge(LspEntity source, LspEntity dest) {
+    if (source.runtimeType != dest.runtimeType) {
+      throw 'Cannot merge ${source.runtimeType} into ${dest.runtimeType}';
+    }
+    if (source is LspEnum && dest is LspEnum) {
+      return LspEnum(
+        name: dest.name,
+        comment: dest.comment ?? source.comment,
+        typeOfValues: dest.typeOfValues,
+        members: [...dest.members, ...source.members],
+      );
+    } else if (source is Interface && dest is Interface) {
+      return Interface(
+        name: dest.name,
+        comment: dest.comment ?? source.comment,
+        typeArgs: dest.typeArgs,
+        baseTypes: [...dest.baseTypes, ...source.baseTypes],
+        members: [...dest.members, ...source.members],
+      );
+    }
+    throw 'Merging ${source.runtimeType}s is not yet supported';
+  }
+
+  List<LspEntity> _mergeTypes(List<LspEntity> types) {
+    final typesByName = {
+      for (final type in types) type.name: type,
+    };
+    assert(types.length == typesByName.length);
+    final typeNames = typesByName.keys.toList();
+    for (final typeName in typeNames) {
+      final targetName = _getMergeTarget(typeName);
+      if (targetName != null) {
+        final type = typesByName[typeName]!;
+        final target = typesByName[targetName]!;
+        typesByName[targetName] = _merge(type, target);
+        typesByName.remove(typeName);
+      }
+    }
+    return typesByName.values.toList();
+  }
+
+  /// Renames types that may have been generated with bad (or long) names.
+  Iterable<LspEntity> _renameTypes(List<LspEntity> types) sync* {
+    const renames = <String, String>{
+      'CodeActionClientCapabilitiesCodeActionLiteralSupportCodeActionKind':
+          'CodeActionLiteralSupportCodeActionKind',
+      'CompletionClientCapabilitiesCompletionItemInsertTextModeSupport':
+          'CompletionItemInsertTextModeSupport',
+      'CompletionClientCapabilitiesCompletionItemTagSupport':
+          'CompletionItemTagSupport',
+      'CompletionClientCapabilitiesCompletionItemResolveSupport':
+          'CompletionItemResolveSupport',
+      'CompletionListItemDefaultsEditRange': 'CompletionItemEditRange',
+      'SignatureHelpClientCapabilitiesSignatureInformationParameterInformation':
+          'SignatureInformationParameterInformation',
+      'TextDocumentFilter2': 'TextDocumentFilterWithScheme',
+      'PrepareRenameResult1': 'PlaceholderAndRange',
+    };
+
+    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,
+            typeArgs: type.typeArgs,
+            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;
+        }
+      }
+      yield type;
+    }
+  }
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
new file mode 100644
index 0000000..7b8919b
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
@@ -0,0 +1,282 @@
+// 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.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:analysis_server/src/utilities/strings.dart';
+import 'package:collection/collection.dart';
+
+import 'meta_model.dart';
+
+/// Reads the LSP 'meta_model.json' file and returns its types.
+class LspMetaModelReader {
+  final _types = <LspEntity>[];
+
+  /// A set of names already used (or reserved) by types that have been read.
+  final Set<String> _typeNames = {};
+
+  /// Characters to strip from member names.
+  final _memberNameInvalidCharPattern = RegExp(r'\$_?');
+
+  /// Patterns to replace with '_' in member names.
+  final _memberNameSeparatorPattern = RegExp(r'/');
+
+  /// Gets all types that have been read from the model JSON.
+  List<LspEntity> get types => _types.toList();
+
+  /// Reads all spec types from [file].
+  LspMetaModel readFile(File file) {
+    final modelJson = file.readAsStringSync();
+    final model = jsonDecode(modelJson) as Map<String, Object?>;
+    return readMap(model);
+  }
+
+  /// Reads all spec types from [model].
+  LspMetaModel readMap(Map<String, dynamic> model) {
+    final requests = model['requests'] as List?;
+    final notifications = model['notifications'] as List?;
+    final structures = model['structures'] as List?;
+    final enums = model['enumerations'] as List?;
+    final typeAliases = model['typeAliases'] as List?;
+    [
+      ...?structures?.map(_readStructure),
+      ...?enums?.map((e) => _readEnum(e)),
+      ...?typeAliases?.map(_readTypeAlias),
+    ].forEach(_addType);
+    final methodNames =
+        _createMethodNamesEnum([...?requests, ...?notifications]);
+    if (methodNames != null) {
+      _addType(methodNames);
+    }
+
+    return LspMetaModel(types);
+  }
+
+  /// Adds [type] to the current list and prevents its name from being used
+  /// by generated interfaces.
+  void _addType(LspEntity type) {
+    _typeNames.add(type.name);
+    _types.add(type);
+  }
+
+  String _camelCase(String str) =>
+      str.substring(0, 1).toLowerCase() + str.substring(1);
+
+  /// Creates an enum for all LSP method names.
+  LspEnum? _createMethodNamesEnum(List items) {
+    Constant toConstant(String value) {
+      final comment = '''Constant for the '$value' method.''';
+      return Constant(
+        name: _generateMemberName(value, camelCase: true),
+        comment: comment,
+        type: TypeReference('string'),
+        value: value,
+      );
+    }
+
+    final methodConstants =
+        items.map((item) => item['method'] as String).map(toConstant).toList();
+
+    if (methodConstants.isEmpty) {
+      return null;
+    }
+
+    final comment = 'All standard LSP Methods read from the JSON spec.';
+    return LspEnum(
+      name: 'Method',
+      comment: comment,
+      typeOfValues: TypeReference('string'),
+      members: methodConstants,
+    );
+  }
+
+  Constant _extractEnumValue(TypeBase parentType, dynamic model) {
+    final name = model['name'] as String;
+    return Constant(
+      name: _generateMemberName(name),
+      comment: model['documentation'] as String?,
+      type: parentType,
+      value: model['value'].toString(),
+    );
+  }
+
+  Member _extractMember(String parentName, dynamic model) {
+    final name = model['name'] as String;
+    var type = _extractType(parentName, name, model['type']);
+
+    // Unions may contain `null` types which we promote up to the field.
+    var allowsNull = false;
+    if (type is UnionType) {
+      final types = type.types;
+
+      // Extract and strip `null`s from the union.
+      if (types.any(isNullType)) {
+        allowsNull = true;
+        type = UnionType(types.whereNot(isNullType).toList());
+      }
+    }
+
+    return Field(
+      name: _generateMemberName(name),
+      comment: model['documentation'] as String?,
+      type: type,
+      allowsNull: allowsNull,
+      allowsUndefined: model['optional'] == true,
+    );
+  }
+
+  /// Reads the type of [model].
+  TypeBase _extractType(String parentName, String? fieldName, dynamic model) {
+    if (model['kind'] == 'reference' || model['kind'] == 'base') {
+      // Reference kinds are other named interfaces defined in the spec, base are
+      // other named types defined elsewhere.
+      return TypeReference(model['name'] as String);
+    } else if (model['kind'] == 'array') {
+      return ArrayType(
+        _extractType(parentName, fieldName, model['element']!),
+      );
+    } else if (model['kind'] == 'map') {
+      final name = fieldName ?? '';
+      return MapType(
+        _extractType(parentName, '${name}Key', model['key']!),
+        _extractType(parentName, '${name}Value', model['value']!),
+      );
+    } else if (model['kind'] == 'literal') {
+      // "Literal" here means an inline/anonymous type.
+      final inlineTypeName = _generateTypeName(
+        parentName,
+        fieldName ?? '',
+      );
+
+      // First record the definition of the anonymous type itself.
+      final members = (model['value']['properties'] as List)
+          .map((p) => _extractMember(inlineTypeName, p))
+          .toList();
+      _addType(Interface.inline(inlineTypeName, members));
+
+      // Then return its name.
+      return TypeReference(inlineTypeName);
+    } else if (model['kind'] == 'stringLiteral') {
+      return LiteralType(
+        TypeReference('string'),
+        model['value'] as String,
+      );
+    } else if (model['kind'] == 'or') {
+      // Ensure the parent name is reserved so we don't try to reuse its name
+      // if we're parsing something without a field name.
+      _typeNames.add(parentName);
+
+      final itemTypes = model['items'] as List;
+      final types = itemTypes.map((item) {
+        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
+      // LSP 3.17 spec only has one tuple which is `[number, number]`.
+      final itemTypes = model['items'] as List;
+      final types = itemTypes.mapIndexed((index, item) {
+        final suffix = index + 1;
+        final name = fieldName ?? '';
+        final thisName = '$name$suffix';
+        return _extractType(parentName, thisName, item);
+      }).toList();
+      return ArrayType(UnionType(types));
+    } else {
+      throw 'Unable to extract type from $model';
+    }
+  }
+
+  /// Generates an available name for a node.
+  ///
+  /// If the computed name is already used, a number will be appended to the
+  /// end.
+  String _generateAvailableTypeName(String containerName, String? fieldName) {
+    final name = _generateTypeName(containerName, fieldName ?? '');
+    final requiresSuffix = fieldName == null;
+    // If the name has already been taken, try appending a number and try
+    // again.
+    String generatedName;
+    var suffixIndex = 1;
+    do {
+      if (suffixIndex > 20) {
+        throw 'Failed to generate an available name for $name';
+      }
+      generatedName =
+          requiresSuffix || suffixIndex > 1 ? '$name$suffixIndex' : name;
+      suffixIndex++;
+    } while (_typeNames.contains(generatedName));
+    return generatedName;
+  }
+
+  /// Generates a valid name for a member.
+  String _generateMemberName(String name, {bool camelCase = false}) {
+    // Replace any seperators like `/` with `_`.
+    name = name.replaceAll(_memberNameSeparatorPattern, '_');
+
+    // Replace out any characters we don't want in member names.
+    name = name.replaceAll(_memberNameInvalidCharPattern, '');
+
+    // TODO(dantup): Remove this condition and always do camelCase in a future
+    //   CL to reduce the migration diff.
+    if (camelCase) {
+      name = _camelCase(name);
+    }
+    return name;
+  }
+
+  /// Generates a valid name for a type.
+  String _generateTypeName(String parent, String child) {
+    // Some classes are private (`_InitializeParams`) but still exposed via
+    // other classes (`InitializeParams`) but the child types still need to be
+    // exposed, so remove any leading underscores.
+    if (parent.startsWith('_')) {
+      parent = parent.substring(1);
+    }
+    return '${capitalize(parent)}${capitalize(child)}';
+  }
+
+  LspEnum _readEnum(dynamic model) {
+    final name = model['name'] as String;
+    final type = TypeReference(name);
+    final baseType = _extractType(name, null, model['type']);
+
+    return LspEnum(
+      name: name,
+      comment: model['documentation'] as String?,
+      typeOfValues: baseType,
+      members: [
+        ...?(model['values'] as List?)?.map((p) => _extractEnumValue(type, p)),
+      ],
+    );
+  }
+
+  LspEntity _readStructure(dynamic model) {
+    final name = model['name'] as String;
+    return Interface(
+      name: name,
+      comment: model['documentation'] as String?,
+      baseTypes: [
+        ...?(model['extends'] as List?)
+            ?.map((e) => TypeReference(e['name'] as String)),
+        ...?(model['mixins'] as List?)
+            ?.map((e) => TypeReference(e['name'] as String)),
+      ],
+      members: [
+        ...?(model['properties'] as List?)?.map((p) => _extractMember(name, p)),
+      ],
+    );
+  }
+
+  TypeAlias _readTypeAlias(dynamic model) {
+    final name = model['name'] as String;
+    return TypeAlias(
+      name: name,
+      comment: model['documentation'] as String?,
+      baseType: _extractType(name, null, model['type']),
+    );
+  }
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
deleted file mode 100644
index 0ca98c3..0000000
--- a/pkg/analysis_server/tool/lsp_spec/typescript.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2018, 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 'typescript_parser.dart';
-
-/// Removes types that are in the spec that we don't want in other signatures.
-bool allowTypeInSignatures(TypeBase type) {
-  // Don't allow arrays of MarkedStrings, but do allow simple MarkedStrings.
-  // The only place that uses these are Hovers and we only send one value
-  // (to match the MarkupString equiv) so the array just makes the types
-  // unnecessarily complicated.
-  if (type is ArrayType) {
-    final elementType = type.elementType;
-    if (elementType is Type && elementType.name == 'MarkedString') {
-      return false;
-    }
-  }
-  return true;
-}
-
-String cleanComment(String comment) {
-  // Remove the start/end comment markers.
-  if (comment.startsWith('/**') && comment.endsWith('*/')) {
-    comment = comment.substring(3, comment.length - 2);
-  } else if (comment.startsWith('//')) {
-    comment = comment.substring(2);
-  }
-
-  final commentLinePrefixes = RegExp(r'\n\s*\* ?');
-  final nonConcurrentNewlines = RegExp(r'\n(?![\n\s\-*])');
-  final newLinesThatRequireReinserting = RegExp(r'\n (\w)');
-  // Remove any Windows newlines from the source.
-  comment = comment.replaceAll('\r', '');
-  // Remove the * prefixes.
-  comment = comment.replaceAll(commentLinePrefixes, '\n');
-  // Remove and newlines that look like wrapped text.
-  comment = comment.replaceAll(nonConcurrentNewlines, ' ');
-  // The above will remove one of the newlines when there are two, so we need
-  // to re-insert newlines for any block that starts immediately after a newline.
-  comment = comment.replaceAllMapped(
-      newLinesThatRequireReinserting, (m) => '\n\n${m.group(1)}');
-  return comment.trim();
-}
-
-/// Improves types in generated code, including:
-///
-/// - Fixes up some enum types that are not as specific as they could be in the
-///   spec. For example, Diagnostic.severity is typed "number" but can be mapped
-///   to the DiagnosticSeverity enum class.
-///
-/// - Narrows unions to single types where they're only generated on the server
-///   and we know we always use a specific type. This avoids wrapping a lot
-///   of code in `EitherX<Y,Z>.tX()` and simplifies the testing of them.
-String? getImprovedType(String interfaceName, String? fieldName) {
-  const improvedTypeMappings = <String, Map<String, String>>{
-    'Diagnostic': {
-      'severity': 'DiagnosticSeverity',
-      'code': 'String',
-      'data': 'object',
-    },
-    'TextDocumentSyncOptions': {
-      'change': 'TextDocumentSyncKind',
-    },
-    'TextDocumentChangeRegistrationOptions': {
-      'syncKind': 'TextDocumentSyncKind',
-    },
-    'FileSystemWatcher': {
-      'kind': 'WatchKind',
-    },
-    'CompletionItem': {
-      'kind': 'CompletionItemKind',
-      'data': 'CompletionItemResolutionInfo',
-    },
-    'CallHierarchyItem': {
-      'data': 'object',
-    },
-    'DocumentHighlight': {
-      'kind': 'DocumentHighlightKind',
-    },
-    'FoldingRange': {
-      'kind': 'FoldingRangeKind',
-    },
-    'SymbolInformation': {
-      'kind': 'SymbolKind',
-    },
-    'ParameterInformation': {
-      'label': 'String',
-    },
-    'ProgressParams': {
-      'value': 'object',
-    },
-    'ServerCapabilities': {
-      'changeNotifications': 'bool',
-    },
-    'TextDocumentEdit': {
-      'edits': 'TextDocumentEditEdits',
-    }
-  };
-
-  final interface = improvedTypeMappings[interfaceName];
-
-  return interface != null ? interface[fieldName] : null;
-}
-
-/// Removes types that are in the spec that we don't want to emit.
-bool includeTypeDefinitionInOutput(AstNode node) {
-  const ignoredTypes = {
-    // InitializeError is not used for v3.0 (Feb 2017) and by dropping it we don't
-    // have to handle any cases where both a namespace and interfaces are declared
-    // with the same name.
-    'InitializeError',
-    // We don't use `InitializeErrorCodes` as it contains only one error code
-    // that has been deprecated and we've never used.
-    'InitializeErrorCodes',
-    // Handled in custom classes now in preperation for JSON meta model which
-    // does not specify them.
-    'Message',
-    'RequestMessage',
-    'NotificationMessage',
-    'ResponseMessage',
-    'ResponseError',
-  };
-  const ignoredPrefixes = {
-    // We don't emit MarkedString because it gets mapped to a simple String
-    // when getting the .dartType for it.
-    'MarkedString'
-  };
-  final shouldIgnore = ignoredTypes.contains(node.name) ||
-      ignoredPrefixes.any((ignore) => node.name.startsWith(ignore));
-  return !shouldIgnore;
-}
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
deleted file mode 100644
index 3f790e3..0000000
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ /dev/null
@@ -1,1075 +0,0 @@
-// Copyright (c) 2018, 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:math';
-
-import 'package:analysis_server/src/utilities/strings.dart' show capitalize;
-import 'package:collection/collection.dart';
-
-import 'codegen_dart.dart';
-import 'typescript.dart';
-
-/// A fabricated field name for indexers in case they result in generation
-/// of type names for inline types.
-const fieldNameForIndexer = 'indexer';
-
-final _keywords = const <String, TokenType>{
-  'class': TokenType.CLASS_KEYWORD,
-  'const': TokenType.CONST_KEYWORD,
-  'enum': TokenType.ENUM_KEYWORD,
-  'export': TokenType.EXPORT_KEYWORD,
-  'extends': TokenType.EXTENDS_KEYWORD,
-  'interface': TokenType.INTERFACE_KEYWORD,
-  'namespace': TokenType.NAMESPACE_KEYWORD,
-  'readonly': TokenType.READONLY_KEYWORD,
-};
-
-final _validIdentifierCharacters = RegExp('[a-zA-Z0-9_]');
-
-bool isAnyType(TypeBase t) =>
-    t is Type &&
-    (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 Type && t.name == 'null';
-
-bool isUndefinedType(TypeBase t) => t is Type && t.name == 'undefined';
-
-List<AstNode> parseString(String input) {
-  final scanner = Scanner(input);
-  final tokens = scanner.scan();
-  final parser = Parser(tokens);
-  return parser.parse();
-}
-
-TypeBase typeOfLiteral(Token token) {
-  final tokenType = token.type;
-  final typeName = tokenType == TokenType.STRING
-      ? 'string'
-      : tokenType == TokenType.NUMBER
-          ? 'int' // all literal numeric values in LSP spec are ints
-          : throw 'Unknown literal type $tokenType';
-  return Type.identifier(typeName);
-}
-
-class ArrayType extends TypeBase {
-  final TypeBase elementType;
-
-  ArrayType(this.elementType);
-
-  @override
-  String get dartType => 'List';
-  @override
-  String get typeArgsString => '<${elementType.dartTypeWithTypeArgs}>';
-}
-
-abstract class AstNode {
-  final Comment? commentNode;
-  final bool isDeprecated;
-  AstNode(this.commentNode)
-      : isDeprecated = commentNode?.text.contains('@deprecated') ?? false;
-  String? get commentText => commentNode?.text;
-
-  String get name;
-}
-
-class Comment extends AstNode {
-  final Token token;
-  final String text;
-
-  Comment(this.token)
-      : text = cleanComment(token.lexeme),
-        super(null);
-
-  @override
-  String get name => throw UnsupportedError('Comments do not have a name.');
-}
-
-class Const extends Member {
-  Token nameToken;
-  TypeBase type;
-  Token valueToken;
-  Const(super.comment, this.nameToken, this.type, this.valueToken);
-
-  @override
-  String get name => nameToken.lexeme;
-
-  String get valueAsLiteral {
-    var lexeme = valueToken.lexeme;
-    if (type.dartType == 'String' && lexeme.contains(r'$')) {
-      // lexeme already includes the quotes as read from the spec.
-      return 'r$lexeme';
-    } else {
-      return lexeme;
-    }
-  }
-}
-
-class Field extends Member {
-  final Token nameToken;
-  final TypeBase type;
-  final bool allowsNull;
-  final bool allowsUndefined;
-  Field(
-    super.comment,
-    this.nameToken,
-    this.type, {
-    required this.allowsNull,
-    required this.allowsUndefined,
-  });
-
-  @override
-  String get name => nameToken.lexeme;
-}
-
-class FixedValueField extends Field {
-  final Token valueToken;
-  FixedValueField(
-    Comment? comment,
-    Token nameToken,
-    this.valueToken,
-    TypeBase type,
-    bool allowsNull,
-    bool allowsUndefined,
-  ) : super(comment, nameToken, type,
-            allowsNull: allowsNull, allowsUndefined: allowsUndefined);
-}
-
-class Indexer extends Member {
-  final TypeBase indexType;
-  final TypeBase valueType;
-  Indexer(
-    super.comment,
-    this.indexType,
-    this.valueType,
-  );
-
-  @override
-  String get name => fieldNameForIndexer;
-}
-
-class InlineInterface extends Interface {
-  InlineInterface(
-    String name,
-    List<Member> members,
-  ) : super(null, Token.identifier(name), [], [], members);
-}
-
-class Interface extends AstNode {
-  final Token nameToken;
-  final List<Token> typeArgs;
-  final List<TypeBase> baseTypes;
-  final List<Member> members;
-
-  Interface(
-    super.comment,
-    this.nameToken,
-    this.typeArgs,
-    this.baseTypes,
-    this.members,
-  ) {
-    baseTypes.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
-    members.sortBy((member) => member.name.toLowerCase());
-  }
-
-  @override
-  String get name => nameToken.lexeme;
-  String get nameWithTypeArgs => '$name$typeArgsString';
-
-  String get typeArgsString => typeArgs.isNotEmpty
-      ? '<${typeArgs.map((t) => t.lexeme).join(', ')}>'
-      : '';
-}
-
-class LiteralType extends TypeBase {
-  final TypeBase type;
-  final String literal;
-
-  LiteralType(this.type, this.literal);
-
-  @override
-  String get dartType => type.dartType;
-
-  @override
-  String get typeArgsString => type.typeArgsString;
-
-  @override
-  String get uniqueTypeIdentifier => '$literal:${super.uniqueTypeIdentifier}';
-}
-
-/// A special class of Union types where the values are all literals of the same
-/// type so the Dart field can be the base type rather than an EitherX<>.
-class LiteralUnionType extends UnionType {
-  final List<LiteralType> literalTypes;
-
-  LiteralUnionType(this.literalTypes) : super(literalTypes);
-
-  @override
-  String get dartType => types.first.dartType;
-
-  @override
-  String get typeArgsString => types.first.typeArgsString;
-}
-
-class MapType extends TypeBase {
-  final TypeBase indexType;
-  final TypeBase valueType;
-
-  MapType(this.indexType, this.valueType);
-
-  @override
-  String get dartType => 'Map';
-
-  @override
-  String get typeArgsString =>
-      '<${indexType.dartTypeWithTypeArgs}, ${valueType.dartTypeWithTypeArgs}>';
-}
-
-abstract class Member extends AstNode {
-  Member(super.comment);
-}
-
-class Namespace extends AstNode {
-  final Token nameToken;
-  final List<Member> members;
-  Namespace(
-    super.comment,
-    this.nameToken,
-    this.members,
-  ) {
-    members.sortBy((member) => member.name.toLowerCase());
-  }
-
-  @override
-  String get name => nameToken.lexeme;
-}
-
-class Parser {
-  final List<Token> _tokens;
-  int _current = 0;
-  final List<AstNode> _nodes = [];
-
-  /// A set of names already used (or reserved) by nodes.
-  final Set<String> _nodeNames = {};
-
-  Parser(this._tokens);
-
-  bool get _isAtEnd => _peek().type == TokenType.EOF;
-
-  List<AstNode> parse() {
-    if (_nodes.isEmpty) {
-      while (!_isAtEnd) {
-        _addNode(_topLevel());
-        // Consume any trailing semicolons.
-        _match([TokenType.SEMI_COLON]);
-      }
-    }
-    return _nodes;
-  }
-
-  /// Adds [node] to the current list and prevents its name from being used
-  /// by generated interfaces.
-  void _addNode(AstNode node) {
-    _nodeNames.add(node.name);
-    _nodes.add(node);
-  }
-
-  /// Returns the current token and moves to the next.
-  Token _advance() => _tokenAt(_current++);
-
-  /// Checks if the next token is [type] without advancing.
-  bool _check(TokenType type) => !_isAtEnd && _peek().type == type;
-
-  Comment? _comment() {
-    if (_peek().type != TokenType.COMMENT) {
-      return null;
-    }
-    return Comment(_advance());
-  }
-
-  Const _const(String containerName, Comment? leadingComment) {
-    _eatUnwantedKeywords();
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    TypeBase? type;
-    if (_match([TokenType.COLON])) {
-      type = _type(containerName, name.lexeme);
-    }
-    final value = _match([TokenType.EQUAL]) ? _advance() : null;
-
-    if (type == null && value != null) {
-      type = typeOfLiteral(value);
-    }
-
-    _consume(TokenType.SEMI_COLON, 'Expected ;');
-    return Const(leadingComment, name, type!, value!);
-  }
-
-  /// Ensures the next token is [type] and moves to the next, throwing [message]
-  /// if not.
-  Token _consume(TokenType type, String message) {
-    // Skip over any inline comments when looking for a specific token.
-    _match([TokenType.COMMENT]);
-
-    if (_check(type)) {
-      return _advance();
-    }
-
-    // The scanner currently reads keywords with specific token types
-    // (eg. TokenType.NAMESPACE_KEYWORD) however v3.16 of the LSP spec also uses
-    // some of these words as identifiers. If the requested type is an identifier
-    // but we have a keyword token, then treat it as an identifier.
-    if (type == TokenType.IDENTIFIER) {
-      final next = !_isAtEnd ? _peek() : null;
-      if (next != null && _isKeyword(next.type)) {
-        _advance();
-        return Token(TokenType.IDENTIFIER, next.lexeme);
-      }
-    }
-
-    throw '$message\n\n${_peek()}';
-  }
-
-  void _eatUnwantedKeywords() {
-    _match([TokenType.EXPORT_KEYWORD]);
-    _match([TokenType.READONLY_KEYWORD]);
-  }
-
-  Namespace _enum(Comment? leadingComment) {
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    _consume(TokenType.LEFT_BRACE, 'Expected {');
-    final consts = <Const>[];
-    while (!_check(TokenType.RIGHT_BRACE)) {
-      consts.add(_enumValue(name.lexeme));
-      // Commas might not be present (eg. for last one).
-      _match([TokenType.COMMA]);
-    }
-    _consume(TokenType.RIGHT_BRACE, 'Expected }');
-
-    return Namespace(leadingComment, name, consts);
-  }
-
-  Const _enumValue(String enumName) {
-    final leadingComment = _comment();
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    TypeBase? type;
-    if (_match([TokenType.COLON])) {
-      type = _type(enumName, name.lexeme);
-    }
-    final value = _match([TokenType.EQUAL]) ? _advance() : null;
-
-    if (type == null && value != null) {
-      type = typeOfLiteral(value);
-    }
-    return Const(leadingComment, name, type!, value!);
-  }
-
-  Field _field(String containerName, Comment? leadingComment) {
-    _eatUnwantedKeywords();
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    var canBeUndefined = _match([TokenType.QUESTION]);
-    _consume(TokenType.COLON, 'Expected :');
-    TypeBase type;
-    Token? value;
-    type = _type(containerName, name.lexeme,
-        includeUndefined: canBeUndefined, improveTypes: true);
-
-    // Some fields have weird comments like this in the spec:
-    //     {@link MessageType}
-    // These seem to be the correct type of the field, while the field is
-    // marked with number.
-    final commentText = leadingComment?.text;
-    if (commentText != null) {
-      final linkTypePattern = RegExp(r'See \{@link (\w+)\}\.?');
-      final linkTypeMatch = linkTypePattern.firstMatch(commentText);
-      if (linkTypeMatch != null) {
-        type = Type.identifier(linkTypeMatch.group(1)!);
-        leadingComment = Comment(Token(TokenType.COMMENT,
-            '// ${commentText.replaceAll(linkTypePattern, '')}'));
-      }
-    }
-
-    // Ideally this would be _consume(), but there are no semi-colons after the
-    // "inline types" since they're blocks.
-    _match([TokenType.SEMI_COLON]);
-
-    // Special handling for fields that have fixed values.
-    if (value != null) {
-      return FixedValueField(
-          leadingComment, name, value, type, false, canBeUndefined);
-    }
-
-    var canBeNull = false;
-    if (type is UnionType) {
-      // Since undefined and null can appear in the union type list but we want to
-      // handle it specially in the code generation, we promote them to fields on
-      // the Field.
-      canBeUndefined |= type.types.any(isUndefinedType);
-      canBeNull = type.types.any((t) => isNullType(t) || isAnyType(t));
-      // Finally, we need to remove them from the union.
-      final remainingTypes = type.types
-          .where((t) => !isNullType(t) && !isUndefinedType(t))
-          .toList();
-
-      // We also remove any types that are deprecated and/or we won't use to
-      // simplify the unions.
-      remainingTypes.removeWhere((t) => !allowTypeInSignatures(t));
-
-      type = _simplifyUnionTypes(remainingTypes);
-    } else if (isAnyType(type)) {
-      // There are values in the spec marked as `any` that allow nulls (for
-      // example, the result field on ResponseMessage can be null for a
-      // successful response that has no return value, eg. shutdown).
-      canBeNull = true;
-    }
-    return Field(leadingComment, name, type,
-        allowsNull: canBeNull, allowsUndefined: canBeUndefined);
-  }
-
-  /// Gets an available name for a node.
-  ///
-  /// If the computed name is already used, a number will be appended to the
-  /// end.
-  String _getAvailableName(String containerName, String? fieldName) {
-    final name = _joinNames(containerName, fieldName ?? '');
-    final requiresSuffix = fieldName == null;
-    // If the name has already been taken, try appending a number and try
-    // again.
-    String generatedName;
-    var suffixIndex = 1;
-    do {
-      if (suffixIndex > 20) {
-        throw 'Failed to generate an available name for $name';
-      }
-      generatedName =
-          requiresSuffix || suffixIndex > 1 ? '$name$suffixIndex' : name;
-      suffixIndex++;
-    } while (_nodeNames.contains(generatedName));
-    return generatedName;
-  }
-
-  Indexer _indexer(String containerName, Comment? leadingComment) {
-    final indexer = _field(containerName, leadingComment);
-    _consume(TokenType.RIGHT_BRACKET, 'Expected ]');
-    _consume(TokenType.COLON, 'Expected :');
-
-    TypeBase type;
-    type = _type(containerName, fieldNameForIndexer, improveTypes: true);
-
-    //_consume(TokenType.RIGHT_BRACE, 'Expected }');
-    _match([TokenType.SEMI_COLON]);
-
-    return Indexer(leadingComment, indexer.type, type);
-  }
-
-  Interface _interface(Comment? leadingComment) {
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    final typeArgs = <Token>[];
-    if (_match([TokenType.LESS])) {
-      while (true) {
-        typeArgs.add(_consume(TokenType.IDENTIFIER, 'Expected identifier'));
-        if (_check(TokenType.GREATER)) {
-          break;
-        }
-        _consume(TokenType.COMMA, 'Expected , or >');
-      }
-      _consume(TokenType.GREATER, 'Expected >');
-    }
-    final baseTypes = <TypeBase>[];
-    if (_match([TokenType.EXTENDS_KEYWORD])) {
-      while (true) {
-        baseTypes.add(_type(name.lexeme, null));
-        if (_check(TokenType.LEFT_BRACE)) {
-          break;
-        }
-        _consume(TokenType.COMMA, 'Expected , or {');
-      }
-    }
-    _consume(TokenType.LEFT_BRACE, 'Expected {');
-    final members = <Member>[];
-    while (!_check(TokenType.RIGHT_BRACE)) {
-      members.add(_member(name.lexeme));
-    }
-
-    _consume(TokenType.RIGHT_BRACE, 'Expected }');
-
-    return Interface(leadingComment, name, typeArgs, baseTypes, members);
-  }
-
-  bool _isKeyword(TokenType type) => _keywords.values.contains(type);
-
-  String _joinNames(String parent, String child) {
-    return '$parent${capitalize(child)}';
-  }
-
-  /// Returns [true] an advances if the next token is one of [types], otherwise
-  /// returns [false].
-  bool _match(List<TokenType> types) {
-    for (final type in types) {
-      if (_check(type)) {
-        _advance();
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  Member _member(String containerName) {
-    final leadingComment = _comment();
-    _eatUnwantedKeywords();
-
-    if (_match([TokenType.CONST_KEYWORD])) {
-      return _const(containerName, leadingComment);
-    } else if (_match([TokenType.LEFT_BRACKET])) {
-      return _indexer(containerName, leadingComment);
-    } else {
-      return _field(containerName, leadingComment);
-    }
-  }
-
-  Namespace _namespace(Comment? leadingComment) {
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    _consume(TokenType.LEFT_BRACE, 'Expected {');
-    final members = <Member>[];
-    while (!_check(TokenType.RIGHT_BRACE)) {
-      members.add(_member(name.lexeme));
-    }
-    _consume(TokenType.RIGHT_BRACE, 'Expected }');
-
-    return Namespace(leadingComment, name, members);
-  }
-
-  /// Returns the next token without advancing.
-  Token _peek() => _tokenAt(_current);
-
-  /// Remove any duplicate types (for ex. if we map multiple types into Object?)
-  /// we don't want to end up with `Object? | Object?`. Key on dartType to
-  /// ensure we different types that will map down to the same type.
-  TypeBase _simplifyUnionTypes(List<TypeBase> types) {
-    final uniqueTypes = Map.fromEntries(
-      types.map((t) => MapEntry(t.uniqueTypeIdentifier, t)),
-    ).values.toList();
-
-    // If our list includes something that maps to Object? as well as other
-    // 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);
-    }
-
-    // Special case to simplify a complex type in the TypeScript spec that is
-    // hard to detect generically and is already simplified in the JSON model.
-    // The first type in the union is fully representable in the second and can
-    // be dropped.
-    // TODO(dantup): Remove this when switching to the JSON model.
-    if (uniqueTypes.length == 2 &&
-        uniqueTypes[0].dartTypeWithTypeArgs == 'List<TextDocumentEdit>' &&
-        uniqueTypes[1].dartTypeWithTypeArgs ==
-            'List<Either4<CreateFile, DeleteFile, RenameFile, TextDocumentEdit>>') {
-      return uniqueTypes[1];
-    }
-
-    return uniqueTypes.length == 1
-        ? uniqueTypes.single
-        : uniqueTypes.every(isLiteralType)
-            ? LiteralUnionType(uniqueTypes.cast<LiteralType>())
-            : UnionType(uniqueTypes);
-  }
-
-  Token _tokenAt(int index) =>
-      index < _tokens.length ? _tokens[index] : Token.EOF;
-
-  AstNode _topLevel() {
-    final leadingComment = _comment();
-    _match([TokenType.EXPORT_KEYWORD]);
-
-    final token = _peek();
-    if (_match([TokenType.NAMESPACE_KEYWORD])) {
-      return _namespace(leadingComment);
-    } else if (_match([TokenType.INTERFACE_KEYWORD])) {
-      return _interface(leadingComment);
-    } else if (_match([TokenType.CLASS_KEYWORD])) {
-      // Classes are the same as interfaces in this spec.
-      return _interface(leadingComment);
-    } else if (_match([TokenType.ENUM_KEYWORD])) {
-      return _enum(leadingComment);
-    } else if (token.type == TokenType.IDENTIFIER && token.lexeme == 'type') {
-      // TODO(dantup): This is a hack... We don't have a TYPE_KEYWORD because
-      // the spec has `type` as an identifier.
-      _advance(); // Eat the 'type' keyword.
-      return _typeAlias(leadingComment);
-    } else {
-      throw 'Unexpected token ${_peek()}';
-    }
-  }
-
-  TypeBase _type(
-    String containerName,
-    String? fieldName, {
-    bool includeUndefined = false,
-    bool improveTypes = false,
-  }) {
-    var types = <TypeBase>[];
-    if (includeUndefined) {
-      types.add(Type.Undefined);
-    }
-    while (true) {
-      TypeBase type;
-      if (_match([TokenType.LEFT_BRACE])) {
-        // Inline interfaces.
-        final generatedName = _getAvailableName(containerName, fieldName);
-        final members = <Member>[];
-        while (!_check(TokenType.RIGHT_BRACE)) {
-          members.add(_member(generatedName));
-        }
-
-        _consume(TokenType.RIGHT_BRACE, 'Expected }');
-        // Some of the inline interfaces have trailing commas (and some do not!)
-        _match([TokenType.COMMA]);
-
-        // If we have a single member that is an indexer type, we can use a Map.
-        if (members.length == 1 && members.single is Indexer) {
-          var indexer = members.single as Indexer;
-          type = MapType(indexer.indexType, indexer.valueType);
-        } else {
-          // Add a synthetic interface to the parsers list of nodes to represent this type.
-          _addNode(InlineInterface(generatedName, members));
-          // Record the type as a simple type that references this interface.
-          type = Type.identifier(generatedName);
-        }
-      } else if (_match([TokenType.LEFT_PAREN])) {
-        // Some types are in (parens), so we just parse the contents as a nested type.
-        type = _type(containerName, fieldName);
-        _consume(TokenType.RIGHT_PAREN, 'Expected )');
-      } else if (_check(TokenType.STRING) || _check(TokenType.NUMBER)) {
-        final token = _advance();
-        // In TS and the spec, literal values can be types:
-        // export const PlainText: 'plaintext' = 'plaintext';
-        // trace?: 'off' | 'messages' | 'verbose';
-        // export const Invoked: 1 = 1;
-        type = LiteralType(typeOfLiteral(token), token.lexeme);
-      } else if (_match([TokenType.LEFT_BRACKET])) {
-        // Tuples will just be converted to List/Array.
-        final tupleElementTypes = <TypeBase>[];
-        while (!_check(TokenType.RIGHT_BRACKET)) {
-          tupleElementTypes.add(_type(containerName, fieldName));
-          // Remove commas in between.
-          _match([TokenType.COMMA]);
-        }
-        _consume(TokenType.RIGHT_BRACKET, 'Expected ]');
-
-        var tupleType = _simplifyUnionTypes(tupleElementTypes);
-        type = ArrayType(tupleType);
-      } else {
-        var typeName = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-        final typeArgs = <TypeBase>[];
-        if (_match([TokenType.LESS])) {
-          while (true) {
-            typeArgs.add(_type(containerName, fieldName));
-            if (_peek().type != TokenType.COMMA) {
-              _consume(TokenType.GREATER, 'Expected >');
-              break;
-            }
-          }
-        }
-
-        type = typeName.lexeme == 'Array'
-            ? ArrayType(typeArgs.single)
-            : Type(typeName, typeArgs);
-      }
-      if (_match([TokenType.LEFT_BRACKET])) {
-        _consume(TokenType.RIGHT_BRACKET, 'Expected ]');
-        type = ArrayType(type);
-      }
-      // TODO(dantup): Handle types like This & That.
-      // For now, map to any.
-      if (_match([TokenType.AMPERSAND])) {
-        while (true) {
-          // Eat as many types/ampersands as we have.
-          _type(containerName, fieldName);
-          if (!_check(TokenType.AMPERSAND)) {
-            break;
-          }
-        }
-        type = Type.Any;
-      }
-
-      types.add(type);
-
-      if (!_match([TokenType.PIPE])) {
-        break;
-      }
-    }
-
-    var type = _simplifyUnionTypes(types);
-
-    // Handle improved type mappings for things that aren't very tight in the spec.
-    if (improveTypes) {
-      final improvedTypeName = getImprovedType(containerName, fieldName);
-      if (improvedTypeName != null) {
-        type = improvedTypeName.endsWith('[]')
-            ? ArrayType(Type.identifier(
-                improvedTypeName.substring(0, improvedTypeName.length - 2)))
-            : Type.identifier(improvedTypeName);
-      }
-    }
-    return type;
-  }
-
-  TypeAlias _typeAlias(Comment? leadingComment) {
-    final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
-    _consume(TokenType.EQUAL, 'Expected =');
-    // Reserve the name for this alias before we start reading its type so that
-    // inline/literal types will not try to compute the same name if they do
-    // not have field names.
-    _nodeNames.add(name.lexeme);
-    final type = _type(name.lexeme, null);
-    if (!_isAtEnd) {
-      _consume(TokenType.SEMI_COLON, 'Expected ;');
-    }
-
-    return TypeAlias(leadingComment, name, type);
-  }
-}
-
-class Scanner {
-  final String _source;
-  int _startOfToken = 0;
-  int _currentPos = 0;
-  final _tokens = <Token>[];
-  Scanner(this._source);
-
-  bool get _isAtEnd => _currentPos >= _source.length;
-  bool get _isNextAtEnd => _currentPos + 1 >= _source.length;
-
-  List<Token> scan() {
-    while (!_isAtEnd) {
-      _startOfToken = _currentPos;
-      _scanToken();
-    }
-    return _tokens;
-  }
-
-  void _addToken(TokenType type, {bool mergeSameTypes = false}) {
-    var text = _source.substring(_startOfToken, _currentPos);
-
-    // Consecutive tokens of some types (for example Comments) are merged
-    // together.
-    if (mergeSameTypes && _tokens.isNotEmpty && type == _tokens.last.type) {
-      text = '${_tokens.last.lexeme}\n$text';
-      _tokens.removeLast();
-    }
-
-    _tokens.add(Token(type, text));
-  }
-
-  String _advance() => _currentPos < _source.length
-      ? _source[_currentPos++]
-      : throw 'Cannot advance past end of source';
-
-  void _identifier() {
-    while (_isAlpha(_peek())) {
-      _advance();
-    }
-
-    final string = _source.substring(_startOfToken, _currentPos);
-    var keyword = _keywords[string];
-    if (keyword != null) {
-      _addToken(keyword);
-    } else {
-      _addToken(TokenType.IDENTIFIER);
-    }
-  }
-
-  bool _isAlpha(String? s) =>
-      s != null && _validIdentifierCharacters.hasMatch(s);
-
-  bool _isDigit(String? s) => s != null && (s.codeUnitAt(0) ^ 0x30) <= 9;
-
-  bool _match(String expected) {
-    if (_isAtEnd || _source[_currentPos] != expected) {
-      return false;
-    }
-    _currentPos++;
-    return true;
-  }
-
-  void _number() {
-    // Optionally process a negative.
-    _match('-');
-    while (_isDigit(_peek())) {
-      _advance();
-    }
-
-    // Handle fractional parts.
-    if (_peek() == '.' && _isDigit(_peekNext())) {
-      // Consume the decimal point.
-      _advance();
-
-      while (_isDigit(_peek())) {
-        _advance();
-      }
-    }
-
-    _addToken(TokenType.NUMBER);
-  }
-
-  String? _peek() => _isAtEnd ? null : _source[_currentPos];
-
-  String? _peekNext() => _isNextAtEnd ? null : _source[_currentPos + 1];
-
-  void _scanToken() {
-    const singleCharTokens = <String, TokenType>{
-      ',': TokenType.COMMA,
-      ';': TokenType.SEMI_COLON,
-      ':': TokenType.COLON,
-      '?': TokenType.QUESTION,
-      '.': TokenType.DOT,
-      '(': TokenType.LEFT_PAREN,
-      ')': TokenType.RIGHT_PAREN,
-      '[': TokenType.LEFT_BRACKET,
-      ']': TokenType.RIGHT_BRACKET,
-      '{': TokenType.LEFT_BRACE,
-      '}': TokenType.RIGHT_BRACE,
-      '*': TokenType.STAR,
-      '&': TokenType.AMPERSAND,
-      '=': TokenType.EQUAL,
-      '|': TokenType.PIPE,
-    };
-
-    final c = _advance();
-    var token = singleCharTokens[c];
-    if (token != null) {
-      _addToken(token);
-      return;
-    }
-    switch (c) {
-      case '/':
-        if (_match('*')) {
-          // Block comment.
-          while (!_isAtEnd && (_peek() != '*' || _peekNext() != '/')) {
-            _advance();
-          }
-          // Eat the closing comment markers detected above.
-          if (!_isAtEnd) {
-            _advance();
-            _advance();
-          }
-          _addToken(TokenType.COMMENT, mergeSameTypes: true);
-        } else if (_match('/')) {
-          // Single line comment.
-          while (_peek() != '\n' && !_isAtEnd) {
-            _advance();
-          }
-          _addToken(TokenType.COMMENT, mergeSameTypes: true);
-        } else {
-          _addToken(TokenType.SLASH);
-        }
-        break;
-      case '<':
-        _addToken(_match('=') ? TokenType.LESS_EQUAL : TokenType.LESS);
-        break;
-      case '>':
-        _addToken(_match('=') ? TokenType.GREATER_EQUAL : TokenType.GREATER);
-        break;
-      case ' ':
-      case '\r':
-      case '\n':
-      case '\t':
-        // Whitespace.
-        break;
-      case '"':
-      case "'":
-        _string(c);
-        break;
-      default:
-        if (_isDigit(c) || c == '-' && _isDigit(_peek())) {
-          _number();
-        } else if (_isAlpha(c)) {
-          _identifier();
-        } else {
-          final start = max(0, _currentPos - 20);
-          final end = min(_currentPos + 20, _source.length);
-          final snippet = _source.substring(start, end);
-          throw "Unexpected character '$c'.\n\n$snippet";
-        }
-        break;
-    }
-  }
-
-  void _string(String terminator) {
-    // TODO(dantup): Handle escape sequences, inc. quotes.
-    while (!_isAtEnd && _peek() != terminator) {
-      _advance();
-
-      if (_isAtEnd) {
-        throw 'Unterminated string.';
-      }
-    }
-
-    // Skip over the closing terminator.
-    _advance();
-
-    _addToken(TokenType.STRING);
-  }
-}
-
-class Token {
-  static final Token EOF = Token(TokenType.EOF, '');
-
-  final TokenType type;
-  final String lexeme;
-
-  Token(this.type, this.lexeme);
-
-  Token.identifier(String identifier) : this(TokenType.IDENTIFIER, identifier);
-
-  @override
-  String toString() => '${type.toString().padRight(25)} '
-      '${lexeme.padRight(10)}\n';
-}
-
-enum TokenType {
-  AMPERSAND,
-  CLASS_KEYWORD,
-  COLON,
-  COMMA,
-  COMMENT,
-  CONST_KEYWORD,
-  DOT,
-  ENUM_KEYWORD,
-  EOF,
-  EQUAL,
-  EXPORT_KEYWORD,
-  EXTENDS_KEYWORD,
-  GREATER_EQUAL,
-  GREATER,
-  IDENTIFIER,
-  INTERFACE_KEYWORD,
-  LEFT_BRACE,
-  LEFT_BRACKET,
-  LEFT_PAREN,
-  LESS_EQUAL,
-  LESS,
-  NAMESPACE_KEYWORD,
-  NUMBER,
-  PIPE,
-  QUESTION,
-  READONLY_KEYWORD,
-  RIGHT_BRACE,
-  RIGHT_BRACKET,
-  RIGHT_PAREN,
-  SEMI_COLON,
-  SLASH,
-  STAR,
-  STRING,
-}
-
-class Type extends TypeBase {
-  static final TypeBase Undefined = Type.identifier('undefined');
-  static final TypeBase Any = Type.identifier('any');
-  final Token nameToken;
-  final List<TypeBase> typeArgs;
-
-  Type(this.nameToken, this.typeArgs) {
-    if (name == 'Array' || name.endsWith('[]')) {
-      throw 'Type should not be used for arrays, use ArrayType instead';
-    }
-  }
-
-  Type.identifier(String identifier) : this(Token.identifier(identifier), []);
-
-  @override
-  String get dartType {
-    // Always resolve type aliases when asked for our Dart type.
-    final resolvedType = resolveTypeAlias(this);
-    if (resolvedType != this) {
-      return resolvedType.dartType;
-    }
-
-    const mapping = <String, String>{
-      'boolean': 'bool',
-      'string': 'String',
-      'number': 'num',
-      'integer': 'int',
-      'uinteger': 'int',
-      'any': 'Object?',
-      'object': 'Object?',
-      // Simplify MarkedString from
-      //     string | { language: string; value: string }
-      // to just String
-      'MarkedString': 'String'
-    };
-
-    final typeName = mapping[name] ?? name;
-    return typeName;
-  }
-
-  String get name => nameToken.lexeme;
-
-  @override
-  String get typeArgsString {
-    // Always resolve type aliases when asked for our Dart type.
-    final resolvedType = resolveTypeAlias(this);
-    if (resolvedType != this) {
-      return resolvedType.typeArgsString;
-    }
-
-    return typeArgs.isNotEmpty
-        ? '<${typeArgs.map((t) => t.dartTypeWithTypeArgs).join(', ')}>'
-        : '';
-  }
-}
-
-class TypeAlias extends AstNode {
-  final Token nameToken;
-  final TypeBase baseType;
-  TypeAlias(
-    super.comment,
-    this.nameToken,
-    this.baseType,
-  );
-
-  @override
-  String get name => nameToken.lexeme;
-}
-
-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
-  /// (for example two types that resolve to "Object?" in Dart).
-  String get uniqueTypeIdentifier => dartTypeWithTypeArgs;
-}
-
-class UnionType extends TypeBase {
-  final List<TypeBase> types;
-
-  UnionType(this.types) {
-    // Ensure types are always sorted alphabetically to simplify sharing code
-    // because `Either2<A, B>` and `Either2<B, A>` are not the same.
-    types.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
-  }
-
-  @override
-  String get dartType {
-    if (types.length > 4) {
-      throw 'Unions of more than 4 types are not supported.';
-    }
-    return 'Either${types.length}';
-  }
-
-  @override
-  String get typeArgsString {
-    final typeArgs = types.map((t) => t.dartTypeWithTypeArgs).join(', ');
-    return '<$typeArgs>';
-  }
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 1bdfcc2..2d52123 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1355,7 +1355,7 @@
           analysisOptions as AnalysisOptionsImpl,
           declaredVariables,
           sourceFactory,
-          libraryContext.elementFactory.libraryOfUri2(library.file.uriStr),
+          libraryContext.elementFactory.libraryOfUri2(library.file.uri),
           libraryContext.elementFactory.analysisSession.inheritanceManager,
           library,
           testingData: testingData,
@@ -1419,7 +1419,7 @@
               analysisOptions as AnalysisOptionsImpl,
               declaredVariables,
               sourceFactory,
-              libraryContext.elementFactory.libraryOfUri2(library.file.uriStr),
+              libraryContext.elementFactory.libraryOfUri2(library.file.uri),
               libraryContext.elementFactory.analysisSession.inheritanceManager,
               library,
               testingData: testingData)
@@ -1697,7 +1697,7 @@
     }
 
     _libraryContext?.elementFactory.removeLibraries(
-      affected.map((e) => e.uriStr).toSet(),
+      affected.map((e) => e.uri).toSet(),
     );
 
     _libraryContext?.elementFactory.replaceAnalysisSession(
@@ -1770,7 +1770,7 @@
       analysisOptions as AnalysisOptionsImpl,
       declaredVariables,
       sourceFactory,
-      libraryContext.elementFactory.libraryOfUri2(library.file.uriStr),
+      libraryContext.elementFactory.libraryOfUri2(library.file.uri),
       libraryContext.elementFactory.analysisSession.inheritanceManager,
       library,
       testingData: testingData,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 2dc8cb3..4f7d8eb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -101,12 +101,7 @@
   /// Get the [LibraryElement] for the given library.
   LibraryElement getLibraryElement(Uri uri) {
     _createElementFactoryTypeProvider();
-    return elementFactory.libraryOfUri2('$uri');
-  }
-
-  /// Return [LibraryElement] if it is ready.
-  LibraryElement? getLibraryElementIfReady(String uriStr) {
-    return elementFactory.libraryOfUriIfReady(uriStr);
+    return elementFactory.libraryOfUri2(uri);
   }
 
   /// Load data required to access elements of the given [targetLibrary].
@@ -121,7 +116,7 @@
 
     Future<void> loadBundle(LibraryCycle cycle) async {
       if (cycle.libraries.isEmpty ||
-          elementFactory.hasLibrary(cycle.libraries.first.uriStr)) {
+          elementFactory.hasLibrary(cycle.libraries.first.uri)) {
         return;
       }
 
@@ -260,8 +255,8 @@
             libraries: cycle.libraries.map((e) => e.uri).toSet(),
           );
           for (var libraryFile in cycle.libraries) {
-            var libraryUriStr = libraryFile.uriStr;
-            var libraryElement = elementFactory.libraryOfUri2(libraryUriStr);
+            var libraryUri = libraryFile.uri;
+            var libraryElement = elementFactory.libraryOfUri2(libraryUri);
             libraryElement.bundleMacroExecutor = bundleMacroExecutor;
           }
         }
@@ -290,9 +285,10 @@
   /// Ensure that type provider is created.
   void _createElementFactoryTypeProvider() {
     if (!analysisContext.hasTypeProvider) {
-      var dartCore = elementFactory.libraryOfUri2('dart:core');
-      var dartAsync = elementFactory.libraryOfUri2('dart:async');
-      elementFactory.createTypeProviders(dartCore, dartAsync);
+      elementFactory.createTypeProviders(
+        elementFactory.dartCoreElement,
+        elementFactory.dartAsyncElement,
+      );
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
index 1a8a0ca..2d8db79 100644
--- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
+++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
@@ -24,10 +24,9 @@
   }
 
   /// Remove hierarchies for classes defined in specified libraries.
-  void removeOfLibraries(Set<String> uriStrSet) {
+  void removeOfLibraries(Set<Uri> uriSet) {
     _map.removeWhere((element, _) {
-      var uriStr = '${element.librarySource.uri}';
-      return uriStrSet.contains(uriStr);
+      return uriSet.contains(element.librarySource.uri);
     });
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index e48d939b..49737ae 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -304,10 +304,9 @@
   }
 
   /// Remove interfaces for classes defined in specified libraries.
-  void removeOfLibraries(Set<String> uriStrSet) {
+  void removeOfLibraries(Set<Uri> uriSet) {
     _interfaces.removeWhere((element, _) {
-      var uriStr = '${element.librarySource.uri}';
-      return uriStrSet.contains(uriStr);
+      return uriSet.contains(element.librarySource.uri);
     });
   }
 
diff --git a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
index 0ffa205..92cb27c 100644
--- a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
@@ -4,8 +4,7 @@
 
 import 'dart:typed_data';
 
-import 'package:analyzer/src/dart/analysis/cache.dart';
-import 'package:collection/collection.dart';
+import 'package:meta/meta.dart';
 
 class CacheData {
   final int id;
@@ -23,64 +22,81 @@
 /// Note that associations are not guaranteed to be persistent. The value
 /// associated with a key can change or become `null` at any point in time.
 abstract class CiderByteStore {
-  /// Return the bytes associated with the errors for given [key] and
-  /// [signature].
+  /// Return the bytes associated with the [key], and increment the reference
+  /// count.
   ///
   /// Return `null` if the association does not exist.
-  CacheData? get(String key, Uint8List signature);
+  Uint8List? get2(String key);
 
-  /// Associate the given [bytes] with the [key] and [signature]. Return the
-  /// [CacheData].
-  CacheData putGet(String key, Uint8List signature, Uint8List bytes);
+  /// Associate [bytes] with [key].
+  /// Return an internalized version of [bytes], the reference count is `1`.
+  ///
+  /// This method will throw an exception if there is already an association
+  /// for the [key]. The client should either use [get2] to access data,
+  /// or first [release2] it.
+  Uint8List putGet2(String key, Uint8List bytes);
 
-  ///  Used to decrement reference count for the given ids, if implemented.
-  void release(Iterable<int> ids);
+  ///  Decrement the reference count for every key in [keys].
+  void release2(Iterable<String> keys);
 }
 
 class CiderByteStoreTestView {
   int length = 0;
 }
 
-class CiderCachedByteStore implements CiderByteStore {
-  final Cache<String, CiderCacheEntry> _cache;
-  int idCounter = 0;
+/// [CiderByteStore] that keeps all data in local memory.
+class MemoryCiderByteStore implements CiderByteStore {
+  @visibleForTesting
+  final Map<String, MemoryCiderByteStoreEntry> map = {};
 
   /// This field gets value only during testing.
   CiderByteStoreTestView? testView;
 
-  CiderCachedByteStore(int maxCacheSize)
-      : _cache = Cache<String, CiderCacheEntry>(
-            maxCacheSize, (v) => v.data.bytes.length);
-
   @override
-  CacheData? get(String key, Uint8List signature) {
-    final entry = _cache.get(key);
-
-    if (entry != null &&
-        const ListEquality<int>().equals(entry.signature, signature)) {
-      return entry.data;
+  Uint8List? get2(String key) {
+    final entry = map[key];
+    if (entry == null) {
+      return null;
     }
-    return null;
+
+    entry.refCount++;
+    return entry.bytes;
   }
 
   @override
-  CacheData putGet(String key, Uint8List signature, Uint8List bytes) {
-    idCounter++;
-    var entry = CiderCacheEntry(signature, CacheData(idCounter, bytes));
-    _cache.put(key, entry);
+  Uint8List putGet2(String key, Uint8List bytes) {
+    if (map.containsKey(key)) {
+      throw StateError('Overwriting is not allowed: $key');
+    }
+
     testView?.length++;
-    return entry.data;
+    map[key] = MemoryCiderByteStoreEntry._(bytes);
+    return bytes;
   }
 
   @override
-  void release(Iterable<int> ids) {
-    // do nothing
+  void release2(Iterable<String> keys) {
+    for (final key in keys) {
+      final entry = map[key];
+      if (entry != null) {
+        entry.refCount--;
+        if (entry.refCount == 0) {
+          map.remove(key);
+        }
+      }
+    }
   }
 }
 
-class CiderCacheEntry {
-  final CacheData data;
-  final Uint8List signature;
+@visibleForTesting
+class MemoryCiderByteStoreEntry {
+  final Uint8List bytes;
+  int refCount = 1;
 
-  CiderCacheEntry(this.signature, this.data);
+  MemoryCiderByteStoreEntry._(this.bytes);
+
+  @override
+  String toString() {
+    return '(length: ${bytes.length}, refCount: $refCount)';
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index 7e108f6..f02eacb 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -127,7 +127,7 @@
     });
 
     performance.run('libraryElement', (performance) {
-      _libraryElement = _elementFactory.libraryOfUri2(_library.uriStr);
+      _libraryElement = _elementFactory.libraryOfUri2(_library.uri);
     });
 
     performance.run('resolveDirectives', (performance) {
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 4a51ff1..137aa84 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -34,6 +34,7 @@
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
+import 'package:meta/meta.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 /// Ensure that the [FileState.libraryCycle] for the [file] and anything it
@@ -137,9 +138,11 @@
     return signatureBuilder.toHex();
   }
 
+  File get resource => _location.resource;
+
   Source get source => _location.source;
 
-  int get unlinkedId => _unlinked.unlinkedId;
+  String get unlinkedKey => _unlinked.unlinkedKey;
 
   UnlinkedUnit get unlinkedUnit => _unlinked.unlinked.unit;
 
@@ -295,6 +298,8 @@
 
   final FileSystemStateTestView testView = FileSystemStateTestView();
 
+  FileSystemTestData? testData;
+
   FileSystemState(
     this._resourceProvider,
     this._byteStore,
@@ -330,16 +335,6 @@
     }
   }
 
-  /// Clears all the cached files. Returns the list of ids of all the removed
-  /// files.
-  Set<int> collectSharedDataIdentifiers() {
-    var result = <int>{};
-    for (var file in _pathToFile.values) {
-      result.add(file._unlinked.unlinkedId);
-    }
-    return result;
-  }
-
   FeatureSet contextFeatureSet(
     String path,
     Uri uri,
@@ -368,6 +363,24 @@
     return featureSetProvider.getLanguageVersion(path, uri);
   }
 
+  /// Notifies this object that it is about to be discarded.
+  ///
+  /// Returns the keys of the artifacts that are no longer used.
+  Set<String> dispose() {
+    final result = <String>{};
+    for (final file in _pathToFile.values) {
+      result.add(file._unlinked.unlinkedKey);
+    }
+    _pathToFile.clear();
+    _uriToFile.clear();
+    return result;
+  }
+
+  @visibleForTesting
+  FileState? getExistingFileForResource(File file) {
+    return _pathToFile[file.path];
+  }
+
   FileState getFileForPath({
     required String path,
     required OperationPerformanceImpl performance,
@@ -498,7 +511,6 @@
 }
 
 class FileSystemStateTestView {
-  final List<String> refreshedFiles = [];
   final List<String> partsDiscoveredLibraries = [];
   Set<String> removedPaths = {};
 }
@@ -541,6 +553,26 @@
   }
 }
 
+class FileSystemTestData {
+  final Map<File, FileTestData> files = {};
+
+  FileTestData forFile(File file) {
+    return files[file] ??= FileTestData._(file);
+  }
+}
+
+class FileTestData {
+  final File file;
+
+  /// We add the key every time we get unlinked data from the byte store.
+  final List<String> unlinkedKeyGet = [];
+
+  /// We add the key every time we put unlinked data into the byte store.
+  final List<String> unlinkedKeyPut = [];
+
+  FileTestData._(this.file);
+}
+
 /// Information about libraries that reference each other, so form a cycle.
 class LibraryCycle {
   /// The libraries that belong to this cycle.
@@ -560,9 +592,9 @@
   /// The hash of all the paths of the files in this cycle.
   late String cyclePathsHash;
 
-  /// The ID of the resolution cache entry.
+  /// The key of the resolution cache entry.
   /// It is `null` if we failed to load libraries of the cycle.
-  int? resolutionId;
+  String? resolutionKey;
 
   LibraryCycle();
 
@@ -713,17 +745,16 @@
   final bool exists;
   final CiderUnlinkedUnit unlinked;
 
-  /// id of the cache entry with unlinked data.
-  final int unlinkedId;
+  /// Key of the cache entry with unlinked data.
+  final String unlinkedKey;
 
   factory _FileStateUnlinked({
     required _FileStateLocation location,
     required FileState? partOfLibrary,
     required OperationPerformanceImpl performance,
   }) {
-    location._fsState.testView.refreshedFiles.add(location.path);
+    final testData = location._fsState.testData?.forFile(location.resource);
 
-    int unlinkedId;
     CiderUnlinkedUnit unlinked;
 
     var digest = performance.run('digest', (performance) {
@@ -734,15 +765,14 @@
 
     var exists = digest.isNotEmpty;
 
-    var unlinkedKey = '${location.path}.unlinked';
+    final unlinkedKey = '${hex.encode(digest)}.unlinked';
     var isUnlinkedFromCache = true;
 
     // Prepare bytes of the unlinked bundle - existing or new.
     // TODO(migration): should not be nullable
     Uint8List? unlinkedBytes;
     {
-      var unlinkedData = location._fsState._byteStore.get(unlinkedKey, digest);
-      unlinkedBytes = unlinkedData?.bytes;
+      unlinkedBytes = location._fsState._byteStore.get2(unlinkedKey);
 
       if (unlinkedBytes == null || unlinkedBytes.isEmpty) {
         isUnlinkedFromCache = false;
@@ -763,14 +793,15 @@
           var unlinkedUnit = serializeAstCiderUnlinked(unit);
           unlinkedBytes = unlinkedUnit.toBytes();
           performance.getDataInt('length').add(unlinkedBytes!.length);
-          unlinkedData = location._fsState._byteStore
-              .putGet(unlinkedKey, digest, unlinkedBytes!);
-          unlinkedBytes = unlinkedData!.bytes;
+          unlinkedBytes =
+              location._fsState._byteStore.putGet2(unlinkedKey, unlinkedBytes!);
+          testData?.unlinkedKeyPut.add(unlinkedKey);
         });
 
         unlinked = CiderUnlinkedUnit.fromBytes(unlinkedBytes!);
+      } else {
+        testData?.unlinkedKeyGet.add(unlinkedKey);
       }
-      unlinkedId = unlinkedData!.id;
     }
 
     // Read the unlinked bundle.
@@ -782,7 +813,7 @@
       digest: digest,
       exists: exists,
       unlinked: unlinked,
-      unlinkedId: unlinkedId,
+      unlinkedKey: unlinkedKey,
     );
     if (isUnlinkedFromCache) {
       performance.run('prefetch', (_) {
@@ -798,7 +829,7 @@
     required this.digest,
     required this.exists,
     required this.unlinked,
-    required this.unlinkedId,
+    required this.unlinkedKey,
   }) : _partOfLibrary = partOfLibrary;
 
   FileState? get partOfLibrary {
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 4c83abd..c99c47f 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -2,6 +2,7 @@
 // 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:collection';
 import 'dart:typed_data';
 
 import 'package:analyzer/dart/analysis/results.dart';
@@ -112,12 +113,12 @@
 
   MicroContextObjects? contextObjects;
 
-  _LibraryContext? libraryContext;
+  LibraryContext? libraryContext;
 
-  /// List of ids for cache elements that are invalidated. Track elements that
+  /// List of keys for cache elements that are invalidated. Track elements that
   /// are invalidated during [changeFile]. Used in [releaseAndClearRemovedIds]
   /// to release the cache items and is then cleared.
-  final Set<int> removedCacheIds = {};
+  final Set<String> removedCacheKeys = {};
 
   /// The cache of file results, cleared on [changeFile].
   ///
@@ -173,21 +174,30 @@
 
     // Schedule disposing references to cached unlinked data.
     for (var removedFile in removedFiles) {
-      removedCacheIds.add(removedFile.unlinkedId);
+      removedCacheKeys.add(removedFile.unlinkedKey);
     }
 
     // Remove libraries represented by removed files.
     // If we need these libraries later, we will relink and reattach them.
     if (libraryContext != null) {
-      libraryContext!.remove(removedFiles, removedCacheIds);
+      libraryContext!.remove(removedFiles, removedCacheKeys);
     }
   }
 
   /// Collects all the cached artifacts and add all the cache id's for the
-  /// removed artifacts to [removedCacheIds].
+  /// removed artifacts to [removedCacheKeys].
+  @Deprecated('Use dispose() instead')
   void collectSharedDataIdentifiers() {
-    removedCacheIds.addAll(fsState!.collectSharedDataIdentifiers());
-    removedCacheIds.addAll(libraryContext!.collectSharedDataIdentifiers());
+    removedCacheKeys.addAll(fsState!.dispose());
+    removedCacheKeys.addAll(libraryContext!.dispose());
+  }
+
+  /// Notifies this object that it is about to be discarded, so it should
+  /// release any shared data.
+  void dispose() {
+    removedCacheKeys.addAll(fsState!.dispose());
+    removedCacheKeys.addAll(libraryContext!.dispose());
+    releaseAndClearRemovedIds();
   }
 
   /// Looks for references to the given Element. All the files currently
@@ -252,7 +262,7 @@
       );
       var file = fileContext.file;
 
-      var errorsSignatureBuilder = ApiSignature();
+      final errorsSignatureBuilder = ApiSignature();
       errorsSignatureBuilder.addBytes(file.libraryCycle.signature);
       errorsSignatureBuilder.addBytes(file.digest);
       final errorsKey = '${errorsSignatureBuilder.toHex()}.errors';
@@ -356,7 +366,7 @@
       );
     });
 
-    return libraryContext!.elementFactory.libraryOfUri2(uriStr);
+    return libraryContext!.elementFactory.libraryOfUri2(uri);
   }
 
   String getLibraryLinkedSignature({
@@ -406,18 +416,30 @@
     var file = fileContext.file;
     var libraryFile = file.partOfLibrary ?? file;
 
+    // Load the library, link if necessary.
     await libraryContext!.load(
       targetLibrary: libraryFile,
       performance: performance,
     );
 
-    _resetContextObjects();
+    // Unload libraries, but don't release the linked data.
+    // If we are the only consumer of it, we will lose it.
+    final linkedKeysToRelease = libraryContext!.unloadAll();
+
+    // Load the library again, the reference count is `>= 2`.
+    await libraryContext!.load(
+      targetLibrary: libraryFile,
+      performance: performance,
+    );
+
+    // Release the linked data, the reference count is `>= 1`.
+    byteStore.release2(linkedKeysToRelease);
   }
 
-  /// Update the cache with list of invalidated ids and clears [removedCacheIds].
+  /// Releases from the cache and clear [removedCacheKeys].
   void releaseAndClearRemovedIds() {
-    byteStore.release(removedCacheIds);
-    removedCacheIds.clear();
+    byteStore.release2(removedCacheKeys);
+    removedCacheKeys.clear();
   }
 
   /// Remove cached [FileState]'s that were not used in the current analysis
@@ -427,7 +449,7 @@
   void removeFilesNotNecessaryForAnalysisOf(List<String> files) {
     var removedFiles = fsState!.removeUnusedFiles(files);
     for (var removedFile in removedFiles) {
-      removedCacheIds.add(removedFile.unlinkedId);
+      removedCacheKeys.add(removedFile.unlinkedKey);
     }
   }
 
@@ -627,7 +649,7 @@
         getFileDigest,
         prefetchFiles,
         isGenerated,
-      );
+      )..testData = testView?.fileSystemTestData;
     }
 
     if (contextObjects == null) {
@@ -643,7 +665,8 @@
         resourceProvider: resourceProvider,
       );
 
-      libraryContext = _LibraryContext(
+      libraryContext = LibraryContext(
+        testView,
         logger,
         resourceProvider,
         byteStore,
@@ -750,13 +773,6 @@
     }
   }
 
-  void _resetContextObjects() {
-    if (libraryContext != null) {
-      contextObjects = null;
-      libraryContext = null;
-    }
-  }
-
   Future<List<CiderSearchMatch>> _searchReferences_Import(
       ImportElement element) async {
     var results = <CiderSearchMatch>[];
@@ -794,6 +810,14 @@
 }
 
 class FileResolverTestView {
+  final FileSystemTestData fileSystemTestData = FileSystemTestData();
+
+  /// Keys: the sorted list of library files.
+  final Map<List<File>, LibraryCycleTestData> libraryCycles = LinkedHashMap(
+    hashCode: Object.hashAll,
+    equals: const ListEquality<File>().equals,
+  );
+
   /// The paths of libraries which were resolved.
   ///
   /// The library path is added every time when it is resolved.
@@ -802,9 +826,17 @@
   void addResolvedLibrary(String path) {
     resolvedLibraries.add(path);
   }
+
+  LibraryCycleTestData forCycle(LibraryCycle cycle) {
+    final files = cycle.libraries.map((e) => e.resource).toList();
+    files.sortBy((file) => file.path);
+
+    return libraryCycles[files] ??= LibraryCycleTestData();
+  }
 }
 
-class _LibraryContext {
+class LibraryContext {
+  final FileResolverTestView? testData;
   final PerformanceLog logger;
   final ResourceProvider resourceProvider;
   final CiderByteStore byteStore;
@@ -814,7 +846,8 @@
 
   Set<LibraryCycle> loadedBundles = Set.identity();
 
-  _LibraryContext(
+  LibraryContext(
+    this.testData,
     this.logger,
     this.resourceProvider,
     this.byteStore,
@@ -827,22 +860,11 @@
     );
   }
 
-  /// Clears all the loaded libraries. Returns the cache ids for the removed
-  /// artifacts.
-  Set<int> collectSharedDataIdentifiers() {
-    var idSet = <int>{};
-
-    void addIfNotNull(int? id) {
-      if (id != null) {
-        idSet.add(id);
-      }
-    }
-
-    for (var cycle in loadedBundles) {
-      addIfNotNull(cycle.resolutionId);
-    }
-    loadedBundles.clear();
-    return idSet;
+  /// Notifies this object that it is about to be discarded.
+  ///
+  /// Returns the keys of the artifacts that are no longer used.
+  Set<String> dispose() {
+    return unloadAll();
   }
 
   /// Load data required to access elements of the given [targetLibrary].
@@ -864,9 +886,8 @@
         await loadBundle(directDependency);
       }
 
-      var resolutionKey = '${cycle.cyclePathsHash}.resolution';
-      var resolutionData = byteStore.get(resolutionKey, cycle.signature);
-      var resolutionBytes = resolutionData?.bytes;
+      var resolutionKey = '${cycle.signatureStr}.resolution';
+      var resolutionBytes = byteStore.get2(resolutionKey);
 
       var unitsInformativeBytes = <Uri, Uint8List>{};
       for (var library in cycle.libraries) {
@@ -939,13 +960,13 @@
         librariesLinked += cycle.libraries.length;
 
         resolutionBytes = linkResult.resolutionBytes;
-        resolutionData =
-            byteStore.putGet(resolutionKey, cycle.signature, resolutionBytes);
-        resolutionBytes = resolutionData.bytes;
+        resolutionBytes = byteStore.putGet2(resolutionKey, resolutionBytes);
         performance.getDataInt('bytesPut').add(resolutionBytes.length);
+        testData?.forCycle(cycle).putKeys.add(resolutionKey);
 
         librariesLinkedTimer.stop();
       } else {
+        testData?.forCycle(cycle).getKeys.add(resolutionKey);
         performance.getDataInt('bytesGet').add(resolutionBytes.length);
         performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
         elementFactory.addBundle(
@@ -956,7 +977,7 @@
           ),
         );
       }
-      cycle.resolutionId = resolutionData!.id;
+      cycle.resolutionKey = resolutionKey;
 
       // We might have just linked dart:core, ensure the type provider.
       _createElementFactoryTypeProvider();
@@ -975,35 +996,65 @@
 
   /// Remove libraries represented by the [removed] files.
   /// If we need these libraries later, we will relink and reattach them.
-  void remove(List<FileState> removed, Set<int> removedIds) {
+  void remove(List<FileState> removed, Set<String> removedKeys) {
     elementFactory.removeLibraries(
-      removed.map((e) => e.uriStr).toSet(),
+      removed.map((e) => e.uri).toSet(),
     );
 
     var removedSet = removed.toSet();
 
-    void addIfNotNull(int? id) {
-      if (id != null) {
-        removedIds.add(id);
+    void addIfNotNull(String? key) {
+      if (key != null) {
+        removedKeys.add(key);
       }
     }
 
     loadedBundles.removeWhere((cycle) {
       if (cycle.libraries.any(removedSet.contains)) {
-        addIfNotNull(cycle.resolutionId);
+        addIfNotNull(cycle.resolutionKey);
         return true;
       }
       return false;
     });
   }
 
+  /// Unloads all loaded bundles.
+  ///
+  /// Returns the keys of the artifacts that are no longer used.
+  Set<String> unloadAll() {
+    final keySet = <String>{};
+    final uriSet = <Uri>{};
+
+    void addIfNotNull(String? key) {
+      if (key != null) {
+        keySet.add(key);
+      }
+    }
+
+    for (var cycle in loadedBundles) {
+      addIfNotNull(cycle.resolutionKey);
+      uriSet.addAll(cycle.libraries.map((e) => e.uri));
+    }
+
+    elementFactory.removeLibraries(uriSet);
+    loadedBundles.clear();
+
+    return keySet;
+  }
+
   /// Ensure that type provider is created.
   void _createElementFactoryTypeProvider() {
     var analysisContext = contextObjects.analysisContext;
     if (!analysisContext.hasTypeProvider) {
-      var dartCore = elementFactory.libraryOfUri2('dart:core');
-      var dartAsync = elementFactory.libraryOfUri2('dart:async');
-      elementFactory.createTypeProviders(dartCore, dartAsync);
+      elementFactory.createTypeProviders(
+        elementFactory.dartCoreElement,
+        elementFactory.dartAsyncElement,
+      );
     }
   }
 }
+
+class LibraryCycleTestData {
+  final List<String> getKeys = [];
+  final List<String> putKeys = [];
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index 508dbaa..5e0f754 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -475,6 +475,15 @@
       return;
     }
 
+    if (propertyType != null) {
+      // If the property is unknown, [UNDEFINED_GETTER] is reported elsewhere.
+      // If it is known, we must report the bad type instantiation here.
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
+        function.identifier,
+        [],
+      );
+    }
     function.accept(_resolver);
     node.staticType = DynamicTypeImpl.instance;
   }
@@ -532,12 +541,18 @@
           rawType: functionType,
           name: function.propertyName.name,
         );
-      } else {
-        // The target is known, but the method is not; [UNDEFINED_GETTER] is
-        // reported elsewhere.
-        node.staticType = DynamicTypeImpl.instance;
+        return;
+      } else if (functionType != null) {
+        // If the property is unknown, [UNDEFINED_GETTER] is reported elsewhere.
+        // If it is known, we must report the bad type instantiation here.
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
+          function.propertyName,
+          [],
+        );
       }
 
+      node.staticType = DynamicTypeImpl.instance;
       return;
     }
 
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index ba4d938..b49eeb8 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3280,7 +3280,7 @@
       var enumElement = expressionType.element;
       if (enumElement.isEnum) {
         var constantNames = enumElement.fields
-            .where((field) => field.isStatic && !field.isSynthetic)
+            .where((field) => field.isEnumConstant)
             .map((field) => field.name)
             .toSet();
 
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0d4d071..49ac589 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -3844,6 +3844,8 @@
       return expression.staticElement;
     } else if (expression is PropertyAccess) {
       return expression.propertyName.staticElement;
+    } else if (expression is SimpleIdentifier) {
+      return expression.staticElement;
     }
     return null;
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index b24d7dc..5b62894 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -33,7 +33,7 @@
   final SummaryDataReader _reader;
   final Map<Uri, Uint8List> _unitsInformativeBytes;
 
-  final Map<String, LibraryReader> libraryMap = {};
+  final Map<Uri, LibraryReader> libraryMap = {};
 
   BundleReader({
     required LinkedElementFactory elementFactory,
@@ -57,16 +57,16 @@
     _reader.offset = librariesOffset;
     var libraryHeaderList = _reader.readTypedList(() {
       return _LibraryHeader(
-        uriStr: _reader.readStringReference(),
+        uri: Uri.parse(_reader.readStringReference()),
         offset: _reader.readUInt30(),
         classMembersLengths: _reader.readUInt30List(),
       );
     });
 
     for (var libraryHeader in libraryHeaderList) {
-      var uriStr = libraryHeader.uriStr;
-      var reference = elementFactory.rootReference.getChild(uriStr);
-      libraryMap[uriStr] = LibraryReader._(
+      var uri = libraryHeader.uri;
+      var reference = elementFactory.rootReference.getChild('$uri');
+      libraryMap[uri] = LibraryReader._(
         elementFactory: elementFactory,
         reader: _reader,
         unitsInformativeBytes: _unitsInformativeBytes,
@@ -1800,7 +1800,7 @@
 /// so that when we need to read this library, we know where it starts without
 /// reading previous libraries.
 class _LibraryHeader {
-  final String uriStr;
+  final Uri uri;
   final int offset;
 
   /// We don't read class members when reading libraries, by performance
@@ -1809,7 +1809,7 @@
   final Uint32List classMembersLengths;
 
   _LibraryHeader({
-    required this.uriStr,
+    required this.uri,
     required this.offset,
     required this.classMembersLengths,
   });
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 00bb912..47f889e 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -67,7 +67,7 @@
     _libraryElement.exports = _exports;
 
     if (!_hasCoreImport) {
-      var dartCore = _linker.elementFactory.libraryOfUri2('dart:core');
+      final dartCore = _linker.elementFactory.dartCoreElement;
       _imports.add(
         ImportElementImpl(-1)
           ..importedLibrary = dartCore
@@ -1234,7 +1234,7 @@
     if (uri == null) {
       return null;
     } else {
-      return _linker.elementFactory.libraryOfUri('$uri');
+      return _linker.elementFactory.libraryOfUri(uri);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/export.dart b/pkg/analyzer/lib/src/summary2/export.dart
index 2f5e590..8e733d7 100644
--- a/pkg/analyzer/lib/src/summary2/export.dart
+++ b/pkg/analyzer/lib/src/summary2/export.dart
@@ -8,10 +8,9 @@
 
 class Export {
   final LibraryBuilder exporter;
-  final LibraryBuilder? exported;
   final List<Combinator> combinators;
 
-  Export(this.exporter, this.exported, this.combinators);
+  Export(this.exporter, this.combinators);
 
   bool addToExportScope(String name, Reference reference) {
     for (Combinator combinator in combinators) {
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 4a1838a..f3b1e50 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -48,12 +48,13 @@
   final List<ImplicitEnumNodes> implicitEnumNodes = [];
 
   /// Local declarations.
-  final Scope localScope = Scope.top();
+  final Scope localScope = Scope();
 
   /// The export scope of the library.
-  final Scope exportScope = Scope.top();
+  final Scope exportScope = Scope();
 
-  final List<Export> exporters = [];
+  /// The `export` directives that export this library.
+  final List<Export> exports = [];
 
   late final LibraryMacroApplier? _macroApplier = () {
     if (!element.featureSet.isEnabled(Feature.macros)) {
@@ -87,7 +88,7 @@
   void addExporters() {
     for (var element in element.exports) {
       var exportedLibrary = element.exportedLibrary;
-      if (exportedLibrary == null) {
+      if (exportedLibrary is! LibraryElementImpl) {
         continue;
       }
 
@@ -104,20 +105,17 @@
       var exportedUri = exportedLibrary.source.uri;
       var exportedBuilder = linker.builders[exportedUri];
 
-      var export = Export(this, exportedBuilder, combinators);
+      var export = Export(this, combinators);
       if (exportedBuilder != null) {
-        exportedBuilder.exporters.add(export);
+        exportedBuilder.exports.add(export);
       } else {
-        var exported = linker.elementFactory.libraryOfUri('$exportedUri');
-        if (exported != null) {
-          var exportedReferences = exported.exportedReferences;
-          for (var reference in exportedReferences) {
-            var name = reference.name;
-            if (reference.isSetter) {
-              export.addToExportScope('$name=', reference);
-            } else {
-              export.addToExportScope(name, reference);
-            }
+        final exportedReferences = exportedLibrary.exportedReferences;
+        for (final reference in exportedReferences) {
+          final name = reference.name;
+          if (reference.isSetter) {
+            export.addToExportScope('$name=', reference);
+          } else {
+            export.addToExportScope(name, reference);
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index f6e224f..e099e37 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -185,28 +185,28 @@
       library.buildInitialExportScope();
     }
 
-    var exporters = <LibraryBuilder>{};
-    var exportees = <LibraryBuilder>{};
+    var exportingBuilders = <LibraryBuilder>{};
+    var exportedBuilders = <LibraryBuilder>{};
 
     for (var library in builders.values) {
       library.addExporters();
     }
 
     for (var library in builders.values) {
-      if (library.exporters.isNotEmpty) {
-        exportees.add(library);
-        for (var exporter in library.exporters) {
-          exporters.add(exporter.exporter);
+      if (library.exports.isNotEmpty) {
+        exportedBuilders.add(library);
+        for (var export in library.exports) {
+          exportingBuilders.add(export.exporter);
         }
       }
     }
 
     var both = <LibraryBuilder>{};
-    for (var exported in exportees) {
-      if (exporters.contains(exported)) {
+    for (var exported in exportedBuilders) {
+      if (exportingBuilders.contains(exported)) {
         both.add(exported);
       }
-      for (var export in exported.exporters) {
+      for (var export in exported.exports) {
         exported.exportScope.forEach(export.addToExportScope);
       }
     }
@@ -214,9 +214,9 @@
     while (true) {
       var hasChanges = false;
       for (var exported in both) {
-        for (var export in exported.exporters) {
-          exported.exportScope.forEach((name, member) {
-            if (export.addToExportScope(name, member)) {
+        for (var export in exported.exports) {
+          exported.exportScope.forEach((name, reference) {
+            if (export.addToExportScope(name, reference)) {
               hasChanges = true;
             }
           });
@@ -231,9 +231,10 @@
   }
 
   void _createTypeSystem() {
-    var coreLib = elementFactory.libraryOfUri2('dart:core');
-    var asyncLib = elementFactory.libraryOfUri2('dart:async');
-    elementFactory.createTypeProviders(coreLib, asyncLib);
+    elementFactory.createTypeProviders(
+      elementFactory.dartCoreElement,
+      elementFactory.dartAsyncElement,
+    );
 
     inheritance = InheritanceManager3();
   }
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index c296291..f329fbd 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -10,12 +10,16 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
 
 class LinkedElementFactory {
+  static final _dartCoreUri = Uri.parse('dart:core');
+  static final _dartAsyncUri = Uri.parse('dart:async');
+
   final AnalysisContextImpl analysisContext;
   AnalysisSessionImpl analysisSession;
   final Reference rootReference;
-  final Map<String, LibraryReader> _libraryReaders = {};
+  final Map<Uri, LibraryReader> _libraryReaders = {};
 
   bool isApplyingInformativeData = false;
 
@@ -28,15 +32,39 @@
     ArgumentError.checkNotNull(analysisSession, 'analysisSession');
   }
 
+  LibraryElementImpl get dartAsyncElement {
+    return libraryOfUri2(_dartAsyncUri);
+  }
+
+  LibraryElementImpl get dartCoreElement {
+    return libraryOfUri2(_dartCoreUri);
+  }
+
   Reference get dynamicRef {
     return rootReference.getChild('dart:core').getChild('dynamic');
   }
 
+  /// Returns URIs for which [LibraryElementImpl] is ready.
+  @visibleForTesting
+  List<Uri> get uriListWithLibraryElements {
+    return rootReference.children
+        .map((reference) => reference.element)
+        .whereType<LibraryElementImpl>()
+        .map((e) => e.source.uri)
+        .toList();
+  }
+
+  /// Returns URIs for which we have readers, but not elements.
+  @visibleForTesting
+  List<Uri> get uriListWithLibraryReaders {
+    return _libraryReaders.keys.toList();
+  }
+
   void addBundle(BundleReader bundle) {
     addLibraries(bundle.libraryMap);
   }
 
-  void addLibraries(Map<String, LibraryReader> libraries) {
+  void addLibraries(Map<Uri, LibraryReader> libraries) {
     _libraryReaders.addAll(libraries);
   }
 
@@ -60,18 +88,18 @@
     return Namespace(exportedNames);
   }
 
-  LibraryElementImpl? createLibraryElementForReading(String uriStr) {
+  LibraryElementImpl? createLibraryElementForReading(Uri uri) {
     var sourceFactory = analysisContext.sourceFactory;
-    var librarySource = sourceFactory.forUri(uriStr);
+    var librarySource = sourceFactory.forUri2(uri);
 
     // The URI cannot be resolved, we don't know the library.
     if (librarySource == null) return null;
 
-    var reader = _libraryReaders[uriStr];
+    var reader = _libraryReaders[uri];
     if (reader == null) {
       var libraryUriList = rootReference.children.map((e) => e.name).toList();
       throw ArgumentError(
-        'Missing library: $uriStr\n'
+        'Missing library: $uri\n'
         'Available libraries: $libraryUriList',
       );
     }
@@ -129,8 +157,8 @@
     }
 
     if (reference.isLibrary) {
-      var uriStr = reference.name;
-      return createLibraryElementForReading(uriStr);
+      final uri = Uri.parse(reference.name);
+      return createLibraryElementForReading(uri);
     }
 
     var parent = reference.parent!.parent!;
@@ -150,60 +178,54 @@
     return element;
   }
 
-  bool hasLibrary(String uriStr) {
+  bool hasLibrary(Uri uri) {
     // We already have the element, linked or read.
-    if (rootReference[uriStr]?.element is LibraryElementImpl) {
+    if (rootReference['$uri']?.element is LibraryElementImpl) {
       return true;
     }
     // No element yet, but we know how to read it.
-    return _libraryReaders[uriStr] != null;
+    return _libraryReaders[uri] != null;
   }
 
-  LibraryElementImpl? libraryOfUri(String uriStr) {
-    var reference = rootReference.getChild(uriStr);
+  LibraryElementImpl? libraryOfUri(Uri uri) {
+    var reference = rootReference.getChild('$uri');
     return elementOfReference(reference) as LibraryElementImpl?;
   }
 
-  LibraryElementImpl libraryOfUri2(String uriStr) {
-    var element = libraryOfUri(uriStr);
+  LibraryElementImpl libraryOfUri2(Uri uri) {
+    var element = libraryOfUri(uri);
     if (element == null) {
-      libraryOfUri(uriStr);
-      throw StateError('No library: $uriStr');
+      libraryOfUri(uri);
+      throw StateError('No library: $uri');
     }
     return element;
   }
 
-  /// Return the [LibraryElementImpl] if it is ready.
-  LibraryElementImpl? libraryOfUriIfReady(String uriStr) {
-    var element = rootReference.getChild(uriStr).element;
-    return element is LibraryElementImpl ? element : null;
-  }
-
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
-  void removeBundle(Set<String> uriStrSet) {
-    removeLibraries(uriStrSet);
+  void removeBundle(Set<Uri> uriSet) {
+    removeLibraries(uriSet);
   }
 
   /// Remove libraries with the specified URIs from the reference tree, and
   /// any session level caches.
-  void removeLibraries(Set<String> uriStrSet) {
-    for (var uriStr in uriStrSet) {
-      _libraryReaders.remove(uriStr);
-      var libraryReference = rootReference.removeChild(uriStr);
+  void removeLibraries(Set<Uri> uriSet) {
+    for (final uri in uriSet) {
+      _libraryReaders.remove(uri);
+      final libraryReference = rootReference.removeChild('$uri');
       _disposeLibrary(libraryReference?.element);
     }
 
-    analysisSession.classHierarchy.removeOfLibraries(uriStrSet);
-    analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
+    analysisSession.classHierarchy.removeOfLibraries(uriSet);
+    analysisSession.inheritanceManager.removeOfLibraries(uriSet);
 
     // If we discard `dart:core` and `dart:async`, we should also discard
     // the type provider.
-    if (uriStrSet.contains('dart:core')) {
-      if (!uriStrSet.contains('dart:async')) {
+    if (uriSet.contains(_dartCoreUri)) {
+      if (!uriSet.contains(_dartAsyncUri)) {
         throw StateError(
           'Expected to link dart:core and dart:async together: '
-          '${uriStrSet.toList()}',
+          '${uriSet.toList()}',
         );
       }
       if (_libraryReaders.isNotEmpty) {
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index 24e180b..e3bba06b 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -525,7 +525,7 @@
 
   @override
   Future<macro.Identifier> resolveIdentifier(Uri library, String name) async {
-    final libraryElement = elementFactory.libraryOfUri2(library.toString());
+    final libraryElement = elementFactory.libraryOfUri2(library);
     final element = libraryElement.scope.lookup(name).getter!;
     return declarationBuilder.fromElement.identifier(element);
   }
diff --git a/pkg/analyzer/lib/src/summary2/scope.dart b/pkg/analyzer/lib/src/summary2/scope.dart
index 1f355ee..ee59adc 100644
--- a/pkg/analyzer/lib/src/summary2/scope.dart
+++ b/pkg/analyzer/lib/src/summary2/scope.dart
@@ -5,12 +5,7 @@
 import 'package:analyzer/src/summary2/reference.dart';
 
 class Scope {
-  final Scope? parent;
-  final Map<String, Reference> map;
-
-  Scope(this.parent, this.map);
-
-  Scope.top() : this(null, <String, Reference>{});
+  final Map<String, Reference> map = {};
 
   void declare(String name, Reference reference) {
     map[name] = reference;
@@ -19,11 +14,4 @@
   void forEach(void Function(String name, Reference reference) f) {
     map.forEach(f);
   }
-
-  Reference? lookup(String name) {
-    var reference = map[name];
-    if (reference != null) return reference;
-
-    return parent?.lookup(name);
-  }
 }
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index f664ce3..8f688a4 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
+import 'package:analyzer/src/dart/micro/library_graph.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
@@ -16,8 +17,11 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:collection/collection.dart';
 import 'package:crypto/crypto.dart';
 import 'package:linter/src/rules.dart';
+import 'package:path/path.dart';
+import 'package:test/test.dart';
 
 import '../resolution/resolution.dart';
 
@@ -25,14 +29,23 @@
 class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
   static final String _testFile = '/workspace/dart/test/lib/test.dart';
 
-  final CiderCachedByteStore byteStore =
-      CiderCachedByteStore(20 * 1024 * 1024 /* 20 MB */);
+  final MemoryCiderByteStore byteStore = MemoryCiderByteStore();
+
+  final FileResolverTestView testData = FileResolverTestView();
 
   final StringBuffer logBuffer = StringBuffer();
   late PerformanceLog logger;
 
   late FileResolver fileResolver;
 
+  final _KeyShorter _keyShorter = _KeyShorter();
+
+  FileSystemState get fsState => fileResolver.fsState!;
+
+  LibraryContext get libraryContext {
+    return fileResolver.libraryContext!;
+  }
+
   Folder get sdkRoot => newFolder('/sdk');
 
   File get testFile => getFile(testFilePath);
@@ -40,11 +53,29 @@
   @override
   String get testFilePath => _testFile;
 
+  String get testPackageLibPath => '$testPackageRootPath/lib';
+
+  String get testPackageRootPath => '$workspaceRootPath/dart/test';
+
+  String get workspaceRootPath => '/workspace';
+
   @override
   void addTestFile(String content) {
     newFile(_testFile, content);
   }
 
+  void assertStateString(String expected) {
+    final buffer = StringBuffer();
+    ResolverStatePrinter(resourceProvider, buffer, _keyShorter)
+        .write(byteStore, fileResolver.fsState!, libraryContext, testData);
+    final actual = buffer.toString();
+
+    if (actual != expected) {
+      print(actual);
+    }
+    expect(actual, expected);
+  }
+
   /// Create a new [FileResolver] into [fileResolver].
   ///
   /// We do this the first time, and to test reusing results from [byteStore].
@@ -68,7 +99,7 @@
       prefetchFiles: null,
       isGenerated: null,
     );
-    fileResolver.testView = FileResolverTestView();
+    fileResolver.testView = testData;
   }
 
   Future<ErrorsResult> getTestErrors() async {
@@ -124,3 +155,176 @@
     }
   }
 }
+
+class ResolverStatePrinter {
+  final ResourceProvider _resourceProvider;
+
+  /// The target sink to print.
+  final StringSink _sink;
+
+  final _KeyShorter _keyShorter;
+
+  String _indent = '';
+
+  ResolverStatePrinter(this._resourceProvider, this._sink, this._keyShorter);
+
+  void write(MemoryCiderByteStore byteStore, FileSystemState fileSystemState,
+      LibraryContext libraryContext, FileResolverTestView testData) {
+    _writelnWithIndent('files');
+    _withIndent(() {
+      final fileMap = testData.fileSystemTestData.files;
+      final fileDataList = fileMap.values.toList();
+      fileDataList.sortBy((fileData) => fileData.file.path);
+
+      for (final fileData in fileDataList) {
+        final file = fileData.file;
+        _writelnWithIndent(_posixPath(file));
+        _withIndent(() {
+          final current = fileSystemState.getExistingFileForResource(file);
+          if (current != null) {
+            _writelnWithIndent('current');
+            _withIndent(() {
+              final unlinkedShort = _keyShorter.shortKey(current.unlinkedKey);
+              _writelnWithIndent('unlinkedKey: $unlinkedShort');
+            });
+          }
+
+          final shortGets = _keyShorter.shortKeys(fileData.unlinkedKeyGet);
+          final shortPuts = _keyShorter.shortKeys(fileData.unlinkedKeyPut);
+          _writelnWithIndent('unlinkedGet: $shortGets');
+          _writelnWithIndent('unlinkedPut: $shortPuts');
+        });
+      }
+    });
+
+    _writelnWithIndent('libraryCycles');
+    _withIndent(() {
+      final entries = testData.libraryCycles.entries
+          .mapKey((key) => key.map(_posixPath).join(' '))
+          .toList();
+      entries.sortBy((e) => e.key);
+
+      final loadedBundlesMap = Map.fromEntries(
+        libraryContext.loadedBundles.map((cycle) {
+          final key = cycle.libraries
+              .map((fileState) => fileState.resource)
+              .map(_posixPath)
+              .join(' ');
+          return MapEntry(key, cycle);
+        }),
+      );
+
+      for (final entry in entries) {
+        _writelnWithIndent(entry.key);
+        _withIndent(() {
+          final current = loadedBundlesMap[entry.key];
+          if (current != null) {
+            _writelnWithIndent('current');
+            _withIndent(() {
+              final short = _keyShorter.shortKey(current.resolutionKey!);
+              _writelnWithIndent('key: $short');
+            });
+          }
+
+          final shortGets = _keyShorter.shortKeys(entry.value.getKeys);
+          final shortPuts = _keyShorter.shortKeys(entry.value.putKeys);
+          _writelnWithIndent('get: $shortGets');
+          _writelnWithIndent('put: $shortPuts');
+        });
+      }
+    });
+
+    _writelnWithIndent('elementFactory');
+    _withIndent(() {
+      final elementFactory = libraryContext.elementFactory;
+      _writeUriList(
+        'hasElement',
+        elementFactory.uriListWithLibraryElements,
+      );
+      _writeUriList(
+        'hasReader',
+        elementFactory.uriListWithLibraryReaders,
+      );
+    });
+
+    _writelnWithIndent('byteStore');
+    _withIndent(() {
+      final groups = byteStore.map.entries.groupListsBy((element) {
+        return element.value.refCount;
+      });
+
+      for (final groupEntry in groups.entries) {
+        final keys = groupEntry.value.map((e) => e.key).toList();
+        final shortKeys = _keyShorter.shortKeys(keys)..sort();
+        _writelnWithIndent('${groupEntry.key}: $shortKeys');
+      }
+    });
+  }
+
+  /// If the path style is `Windows`, returns the corresponding Posix path.
+  /// Otherwise the path is already a Posix path, and it is returned as is.
+  String _posixPath(File file) {
+    final pathContext = _resourceProvider.pathContext;
+    if (pathContext.style == Style.windows) {
+      final components = pathContext.split(file.path);
+      return '/${components.skip(1).join('/')}';
+    } else {
+      return file.path;
+    }
+  }
+
+  void _withIndent(void Function() f) {
+    var indent = _indent;
+    _indent = '$_indent  ';
+    f();
+    _indent = indent;
+  }
+
+  void _writelnWithIndent(String line) {
+    _sink.write(_indent);
+    _sink.writeln(line);
+  }
+
+  void _writeUriList(String name, Iterable<Uri> uriIterable) {
+    final uriStrList = uriIterable.map((uri) => '$uri').toList();
+    if (uriStrList.isNotEmpty) {
+      uriStrList.sort();
+      _writelnWithIndent(name);
+      _withIndent(() {
+        for (final uriStr in uriStrList) {
+          _writelnWithIndent(uriStr);
+        }
+      });
+    }
+  }
+}
+
+/// Keys in the byte store are long hashes, which are hard to read.
+/// So, we generate short unique versions for them.
+class _KeyShorter {
+  final Map<String, String> _keyToShort = {};
+  final Map<String, String> _shortToKey = {};
+
+  String shortKey(String key) {
+    var short = _keyToShort[key];
+    if (short == null) {
+      short = 'k${_keyToShort.length.toString().padLeft(2, '0')}';
+      _keyToShort[key] = short;
+      _shortToKey[short] = key;
+    }
+    return short;
+  }
+
+  List<String> shortKeys(List<String> keys) {
+    return keys.map(shortKey).toList();
+  }
+}
+
+extension<K, V> on Iterable<MapEntry<K, V>> {
+  Iterable<MapEntry<K2, V>> mapKey<K2>(K2 Function(K key) convertKey) {
+    return map((e) {
+      final newKey = convertKey(e.key);
+      return MapEntry(newKey, e.value);
+    });
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 4f726b3..fe558a7 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
-import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:analyzer/src/dart/micro/utils.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -26,83 +25,289 @@
 
 @reflectiveTest
 class FileResolver_changeFile_Test extends FileResolutionTest {
-  late final String aPath;
-  late final String bPath;
-  late final String cPath;
-
-  @override
-  void setUp() {
-    super.setUp();
-    aPath = convertPath('/workspace/dart/test/lib/a.dart');
-    bPath = convertPath('/workspace/dart/test/lib/b.dart');
-    cPath = convertPath('/workspace/dart/test/lib/c.dart');
-  }
-
   test_changeFile_refreshedFiles() async {
-    newFile(aPath, r'''
+    final a = newFile('$testPackageLibPath/a.dart', r'''
 class A {}
 ''');
 
-    newFile(bPath, r'''
+    newFile('$testPackageLibPath/b.dart', r'''
 class B {}
 ''');
 
-    newFile(cPath, r'''
+    final c = newFile('$testPackageLibPath/c.dart', r'''
 import 'a.dart';
 import 'b.dart';
 ''');
 
     // First time we refresh everything.
-    await resolveFile(cPath);
-    _assertRefreshedFiles([aPath, bPath, cPath], withSdk: true);
+    await resolveFile(c.path);
+
+    const state_1 = r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06]
+  /workspace/dart/test/lib/c.dart
+    current
+      unlinkedKey: k07
+    unlinkedGet: []
+    unlinkedPut: [k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k09
+    get: []
+    put: [k09]
+  /workspace/dart/test/lib/b.dart
+    current
+      key: k10
+    get: []
+    put: [k10]
+  /workspace/dart/test/lib/c.dart
+    current
+      key: k11
+    get: []
+    put: [k11]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/b.dart
+    package:dart.test/c.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11]
+''';
+    assertStateString(state_1);
 
     // Without changes we refresh nothing.
-    await resolveFile(cPath);
-    _assertRefreshedFiles([]);
+    await resolveFile(c.path);
+    assertStateString(state_1);
 
     // We already know a.dart, refresh nothing.
-    await resolveFile(aPath);
-    _assertRefreshedFiles([]);
+    await resolveFile(a.path);
+    assertStateString(state_1);
 
-    // Change a.dart, refresh a.dart and c.dart, but not b.dart
-    fileResolver.changeFile(aPath);
-    await resolveFile(cPath);
-    _assertRefreshedFiles([aPath, cPath]);
+    // Change a.dart, discard data for a.dart and c.dart, but not b.dart
+    fileResolver.changeFile(a.path);
+    fileResolver.releaseAndClearRemovedIds();
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06]
+  /workspace/dart/test/lib/c.dart
+    unlinkedGet: []
+    unlinkedPut: [k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    get: []
+    put: [k09]
+  /workspace/dart/test/lib/b.dart
+    current
+      key: k10
+    get: []
+    put: [k10]
+  /workspace/dart/test/lib/c.dart
+    get: []
+    put: [k11]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/b.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k06, k08, k10]
+''');
+
+    // Resolve, read again a.dart and c.dart
+    await resolveFile(c.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05, k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06]
+  /workspace/dart/test/lib/c.dart
+    current
+      unlinkedKey: k07
+    unlinkedGet: []
+    unlinkedPut: [k07, k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k09
+    get: []
+    put: [k09, k09]
+  /workspace/dart/test/lib/b.dart
+    current
+      key: k10
+    get: []
+    put: [k10]
+  /workspace/dart/test/lib/c.dart
+    current
+      key: k11
+    get: []
+    put: [k11, k11]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/b.dart
+    package:dart.test/c.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11]
+''');
   }
 
   test_changeFile_resolution() async {
-    newFile(aPath, r'''
+    final a = newFile('/workspace/dart/test/lib/a.dart', r'''
 class A {}
 ''');
 
-    newFile(bPath, r'''
+    final b = newFile('/workspace/dart/test/lib/b.dart', r'''
 import 'a.dart';
 void f(A a, B b) {}
 ''');
 
-    result = await resolveFile(bPath);
+    result = await resolveFile(b.path);
     assertErrorsInResolvedUnit(result, [
       error(CompileTimeErrorCode.UNDEFINED_CLASS, 29, 1),
     ]);
 
-    newFile(aPath, r'''
+    newFile(a.path, r'''
 class A {}
 class B {}
 ''');
-    fileResolver.changeFile(aPath);
+    fileResolver.changeFile(a.path);
 
-    result = await resolveFile(bPath);
+    result = await resolveFile(b.path);
     assertErrorsInResolvedUnit(result, []);
   }
 
   test_changeFile_resolution_flushInheritanceManager() async {
-    newFile(aPath, r'''
+    final a = newFile('/workspace/dart/test/lib/a.dart', r'''
 class A {
   final int foo = 0;
 }
 ''');
 
-    newFile(bPath, r'''
+    final b = newFile('/workspace/dart/test/lib/b.dart', r'''
 import 'a.dart';
 
 void f(A a) {
@@ -110,30 +315,30 @@
 }
 ''');
 
-    result = await resolveFile(bPath);
+    result = await resolveFile(b.path);
     assertErrorsInResolvedUnit(result, [
       error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 36, 3),
     ]);
 
-    newFile(aPath, r'''
+    newFile(a.path, r'''
 class A {
   int foo = 0;
 }
 ''');
-    fileResolver.changeFile(aPath);
+    fileResolver.changeFile(a.path);
 
-    result = await resolveFile(bPath);
+    result = await resolveFile(b.path);
     assertErrorsInResolvedUnit(result, []);
   }
 
   test_changeFile_resolution_missingChangeFileForPart() async {
-    newFile(aPath, r'''
+    final a = newFile('/workspace/dart/test/lib/a.dart', r'''
 part 'b.dart';
 
 var b = B(0);
 ''');
 
-    result = await resolveFile(aPath);
+    result = await resolveFile(a.path);
     assertErrorsInResolvedUnit(result, [
       error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 5, 8),
       error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 24, 1),
@@ -141,16 +346,16 @@
 
     // Update a.dart, and notify the resolver. We need this to have at least
     // one change, so that we decided to rebuild the library summary.
-    newFile(aPath, r'''
+    newFile(a.path, r'''
 part 'b.dart';
 
 var b = B(1);
 ''');
-    fileResolver.changeFile(aPath);
+    fileResolver.changeFile(a.path);
 
     // Update b.dart, but do not notify the resolver.
     // If we try to read it now, it will throw.
-    newFile(bPath, r'''
+    final b = newFile('/workspace/dart/test/lib/b.dart', r'''
 part of 'a.dart';
 
 class B {
@@ -159,63 +364,426 @@
 ''');
 
     expect(() async {
-      await resolveFile(aPath);
+      await resolveFile(a.path);
     }, throwsStateError);
 
     // Notify the resolver about b.dart, it is OK now.
-    fileResolver.changeFile(bPath);
-    result = await resolveFile(aPath);
+    fileResolver.changeFile(b.path);
+    result = await resolveFile(a.path);
     assertErrorsInResolvedUnit(result, []);
   }
 
   test_changePartFile_refreshedFiles() async {
-    newFile(aPath, r'''
+    newFile('/workspace/dart/test/lib/a.dart', r'''
 part 'b.dart';
 
 class A {}
 ''');
 
-    newFile(bPath, r'''
+    final b = newFile('/workspace/dart/test/lib/b.dart', r'''
 part of 'a.dart';
 
 class B extends A {}
 ''');
 
-    newFile(cPath, r'''
+    // First time we refresh everything.
+    await resolveFile(b.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k07
+    get: []
+    put: [k07]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08]
+''');
+
+    // Change b.dart, discard both b.dart and a.dart
+    fileResolver.changeFile(b.path);
+    fileResolver.releaseAndClearRemovedIds();
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    unlinkedGet: []
+    unlinkedPut: [k06]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k07
+    get: []
+    put: [k07]
+  /workspace/dart/test/lib/a.dart
+    get: []
+    put: [k08]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+byteStore
+  1: [k00, k01, k02, k03, k04, k07]
+''');
+
+    // Resolve, read a.dart and b.dart
+    await resolveFile(b.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05, k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06, k06]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k07
+    get: []
+    put: [k07]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k08
+    get: []
+    put: [k08, k08]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08]
+''');
+  }
+
+  test_changePartFile_refreshedFiles_transitive() async {
+    newFile('/workspace/dart/test/lib/a.dart', r'''
+part 'b.dart';
+
+class A {}
+''');
+
+    final b = newFile('/workspace/dart/test/lib/b.dart', r'''
+part of 'a.dart';
+
+class B extends A {}
+''');
+
+    final c = newFile('/workspace/dart/test/lib/c.dart', r'''
 import 'a.dart';
 ''');
 
-    // First time we refresh everything.
-    await resolveFile(bPath);
-    _assertRefreshedFiles([aPath, bPath], withSdk: true);
-    // Change b.dart, refresh a.dart
-    fileResolver.changeFile(bPath);
-    await resolveFile(bPath);
-    _assertRefreshedFiles([aPath, bPath]);
-    // now with c.dart
-    await resolveFile(cPath);
-    _assertRefreshedFiles([cPath]);
-    fileResolver.changeFile(bPath);
-    await resolveFile(cPath);
-    _assertRefreshedFiles([aPath, bPath, cPath]);
-  }
+    await resolveFile(c.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06]
+  /workspace/dart/test/lib/c.dart
+    current
+      unlinkedKey: k07
+    unlinkedGet: []
+    unlinkedPut: [k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k09
+    get: []
+    put: [k09]
+  /workspace/dart/test/lib/c.dart
+    current
+      key: k10
+    get: []
+    put: [k10]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/c.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10]
+''');
 
-  void _assertRefreshedFiles(List<String> expected, {bool withSdk = false}) {
-    var expectedPlusSdk = expected.toSet();
+    // Should invalidate a.dart, b.dart, c.dart
+    fileResolver.changeFile(b.path);
+    fileResolver.releaseAndClearRemovedIds();
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    unlinkedGet: []
+    unlinkedPut: [k06]
+  /workspace/dart/test/lib/c.dart
+    unlinkedGet: []
+    unlinkedPut: [k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    get: []
+    put: [k09]
+  /workspace/dart/test/lib/c.dart
+    get: []
+    put: [k10]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+byteStore
+  1: [k00, k01, k02, k03, k04, k08]
+''');
 
-    if (withSdk) {
-      expectedPlusSdk
-        ..add(convertPath('/sdk/lib/_internal/internal.dart'))
-        ..add(convertPath('/sdk/lib/async/async.dart'))
-        ..add(convertPath('/sdk/lib/async/stream.dart'))
-        ..add(convertPath('/sdk/lib/core/core.dart'))
-        ..add(convertPath('/sdk/lib/math/math.dart'));
-    }
-
-    var refreshedFiles = fileResolver.fsState!.testView.refreshedFiles;
-    expect(refreshedFiles, unorderedEquals(expectedPlusSdk));
-
-    refreshedFiles.clear();
+    // Read again a.dart, b.dart, c.dart
+    await resolveFile(c.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05, k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k06
+    unlinkedGet: []
+    unlinkedPut: [k06, k06]
+  /workspace/dart/test/lib/c.dart
+    current
+      unlinkedKey: k07
+    unlinkedGet: []
+    unlinkedPut: [k07, k07]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k08
+    get: []
+    put: [k08]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k09
+    get: []
+    put: [k09, k09]
+  /workspace/dart/test/lib/c.dart
+    current
+      key: k10
+    get: []
+    put: [k10, k10]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/c.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10]
+''');
   }
 }
 
@@ -328,17 +896,102 @@
     assertType(findElement.topVar('b').type, 'int');
   }
 
-  test_collectSharedDataIdentifiers() async {
-    var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
-
-    newFile(aPath, r'''
+  test_dispose() async {
+    final a = newFile('$testPackageLibPath/a.dart', r'''
 class A {}
 ''');
 
-    await resolveFile(aPath);
-    fileResolver.collectSharedDataIdentifiers();
-    expect(fileResolver.removedCacheIds.length,
-        (fileResolver.byteStore as CiderCachedByteStore).testView!.length);
+    // After resolution the byte store contains unlinked data for files,
+    // and linked data for loaded bundles.
+    await resolveFile(a.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: []
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k07
+    get: []
+    put: [k07]
+elementFactory
+  hasElement
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07]
+''');
+
+    fileResolver.dispose();
+
+    // After dispose() we don't have any loaded libraries or files.
+    // The byte store is empty - no unlinked or linked data.
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    get: []
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    get: []
+    put: [k07]
+elementFactory
+byteStore
+''');
   }
 
   test_elements_export_dartCoreDynamic() async {
@@ -824,22 +1477,426 @@
     assertNoErrorsInResult();
   }
 
+  test_linkLibraries() async {
+    final a = newFile('$testPackageLibPath/a.dart', r'''
+final a = 0;
+''');
+
+    final b = newFile('$testPackageLibPath/b.dart', r'''
+import 'a.dart';
+final b = a;
+''');
+
+    await fileResolver.linkLibraries2(path: a.path);
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06]
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k07
+    get: [k07]
+    put: [k07]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07]
+''');
+
+    await fileResolver.getLibraryByUri2(
+      uriStr: 'package:dart.test/a.dart',
+    );
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06]
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k07
+    get: [k07]
+    put: [k07]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+    package:dart.test/a.dart
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07]
+''');
+
+    await fileResolver.linkLibraries2(path: b.path);
+
+    // We discarded all libraries, so each one has `get` and `put`.
+    // We did not discard files, so only `unlinkedPut`.
+    // The reference count for each data is exactly `1`.
+    assertStateString('''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k08
+    unlinkedGet: []
+    unlinkedPut: [k08]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06, k06]
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k07
+    get: [k07, k07]
+    put: [k07]
+  /workspace/dart/test/lib/b.dart
+    current
+      key: k09
+    get: [k09]
+    put: [k09]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/b.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09]
+''');
+
+    final b_library = await fileResolver.getLibraryByUri2(
+      uriStr: 'package:dart.test/b.dart',
+    );
+
+    // Ask types for top-level variables.
+    final b_unit = b_library.definingCompilationUnit;
+    for (final topLevelVariable in b_unit.topLevelVariables) {
+      topLevelVariable.type;
+    }
+
+    // All types are stored in the bundle for b.dart itself, we don't need to
+    // read a.dart to access them, so we keep it as a reader.
+    assertStateString('''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/a.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+  /workspace/dart/test/lib/b.dart
+    current
+      unlinkedKey: k08
+    unlinkedGet: []
+    unlinkedPut: [k08]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06, k06]
+    put: [k06]
+  /workspace/dart/test/lib/a.dart
+    current
+      key: k07
+    get: [k07, k07]
+    put: [k07]
+  /workspace/dart/test/lib/b.dart
+    current
+      key: k09
+    get: [k09]
+    put: [k09]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+    package:dart.test/b.dart
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/a.dart
+    package:dart.test/b.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07, k08, k09]
+''');
+  }
+
   test_linkLibraries_getErrors() async {
     addTestFile(r'''
 var a = b;
 var foo = 0;
 ''');
 
-    var path = convertPath('/workspace/dart/test/lib/test.dart');
-    await fileResolver.linkLibraries2(path: path);
+    await fileResolver.linkLibraries2(path: testFile.path);
+
+    // We discarded all libraries, so each one has `get` and `put`.
+    // We did not discard files, so only `unlinkedPut`.
+    // The library for the test file has reader, but not the element yet.
+    // `dart:core` and `dart` have element because of `TypeProvider`.
+    // The reference count for each data is exactly `1`.
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/test.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06]
+    put: [k06]
+  /workspace/dart/test/lib/test.dart
+    current
+      key: k07
+    get: [k07]
+    put: [k07]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/test.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07]
+''');
 
     var result = await getTestErrors();
-    expect(result.path, path);
+    expect(result.path, testFile.path);
     expect(result.uri.toString(), 'package:dart.test/test.dart');
     assertErrorsInList(result.errors, [
       error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 8, 1),
     ]);
     expect(result.lineInfo.lineStarts, [0, 11, 24]);
+
+    // We created the library element for the test file, using the reader.
+    assertStateString(r'''
+files
+  /sdk/lib/_internal/internal.dart
+    current
+      unlinkedKey: k00
+    unlinkedGet: []
+    unlinkedPut: [k00]
+  /sdk/lib/async/async.dart
+    current
+      unlinkedKey: k01
+    unlinkedGet: []
+    unlinkedPut: [k01]
+  /sdk/lib/async/stream.dart
+    current
+      unlinkedKey: k02
+    unlinkedGet: []
+    unlinkedPut: [k02]
+  /sdk/lib/core/core.dart
+    current
+      unlinkedKey: k03
+    unlinkedGet: []
+    unlinkedPut: [k03]
+  /sdk/lib/math/math.dart
+    current
+      unlinkedKey: k04
+    unlinkedGet: []
+    unlinkedPut: [k04]
+  /workspace/dart/test/lib/test.dart
+    current
+      unlinkedKey: k05
+    unlinkedGet: []
+    unlinkedPut: [k05]
+libraryCycles
+  /sdk/lib/_internal/internal.dart /sdk/lib/async/async.dart /sdk/lib/core/core.dart /sdk/lib/math/math.dart
+    current
+      key: k06
+    get: [k06]
+    put: [k06]
+  /workspace/dart/test/lib/test.dart
+    current
+      key: k07
+    get: [k07]
+    put: [k07]
+elementFactory
+  hasElement
+    dart:async
+    dart:core
+    package:dart.test/test.dart
+  hasReader
+    dart:_internal
+    dart:async
+    dart:core
+    dart:math
+    package:dart.test/test.dart
+byteStore
+  1: [k00, k01, k02, k03, k04, k05, k06, k07]
+''');
   }
 
   test_nameOffset_class_method_fromBytes() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index 81e03b3..a569dbc 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -25,7 +25,14 @@
 }
 ''');
 
-    assertType(findNode.listLiteral('[]'), 'List<int>');
+    final node = findNode.listLiteral('[]');
+    assertResolvedNodeText(node, r'''
+ListLiteral
+  leftBracket: [
+  rightBracket: ]
+  parameter: self::@enum::E::@constructor::•::@parameter::a
+  staticType: List<int>
+''');
   }
 
   test_constructor_argumentList_namedType() async {
@@ -36,16 +43,37 @@
 }
 ''');
 
-    assertNamedType(
-      findNode.namedType('double'),
-      doubleElement,
-      'double',
-    );
-
-    assertType(
-      findNode.genericFunctionType('void Function'),
-      'void Function(double)',
-    );
+    final node = findNode.genericFunctionType('Function');
+    assertResolvedNodeText(node, r'''
+GenericFunctionType
+  returnType: NamedType
+    name: SimpleIdentifier
+      token: void
+      staticElement: <null>
+      staticType: null
+    type: void
+  functionKeyword: Function
+  parameters: FormalParameterList
+    leftParenthesis: (
+    parameter: SimpleFormalParameter
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+          staticElement: dart:core::@class::double
+          staticType: null
+        type: double
+      declaredElement: @-1
+      declaredElementType: double
+    rightParenthesis: )
+  declaredElement: GenericFunctionTypeElement
+    parameters
+      <empty>
+        kind: required positional
+        type: double
+    returnType: void
+    type: void Function(double)
+  type: void Function(double)
+''');
   }
 
   test_constructor_generic_noTypeArguments_named() async {
@@ -56,22 +84,35 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: elementMatcher(
-        findElement.constructor('named'),
-        substitution: {'T': 'int'},
-      ),
-    );
-
-    assertParameterElement(
-      findNode.integerLiteral('42'),
-      elementMatcher(
-        findElement.parameter('a'),
-        substitution: {'T': 'int'},
-      ),
-    );
+    final node = findNode.enumConstantDeclaration('v.');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    constructorSelector: ConstructorSelector
+      period: .
+      name: SimpleIdentifier
+        token: named
+        staticElement: <null>
+        staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: ParameterMember
+            base: self::@enum::E::@constructor::named::@parameter::a
+            substitution: {T: int}
+          staticType: int
+      rightParenthesis: )
+  constructorElement: ConstructorMember
+    base: self::@enum::E::@constructor::named
+    substitution: {T: int}
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_generic_noTypeArguments_unnamed() async {
@@ -82,22 +123,29 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: elementMatcher(
-        findElement.enum_('E').unnamedConstructor,
-        substitution: {'T': 'int'},
-      ),
-    );
-
-    assertParameterElement(
-      findNode.integerLiteral('42'),
-      elementMatcher(
-        findElement.parameter('a'),
-        substitution: {'T': 'int'},
-      ),
-    );
+    final node = findNode.enumConstantDeclaration('v(');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: ParameterMember
+            base: self::@enum::E::@constructor::•::@parameter::a
+            substitution: {T: int}
+          staticType: int
+      rightParenthesis: )
+  constructorElement: ConstructorMember
+    base: self::@enum::E::@constructor::•
+    substitution: {T: int}
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_generic_typeArguments_named() async {
@@ -108,28 +156,45 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: elementMatcher(
-        findElement.constructor('named'),
-        substitution: {'T': 'double'},
-      ),
-    );
-
-    assertNamedType(
-      findNode.namedType('double'),
-      doubleElement,
-      'double',
-    );
-
-    assertParameterElement(
-      findNode.integerLiteral('42'),
-      elementMatcher(
-        findElement.parameter('a'),
-        substitution: {'T': 'double'},
-      ),
-    );
+    final node = findNode.enumConstantDeclaration('v<');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    typeArguments: TypeArgumentList
+      leftBracket: <
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: double
+            staticElement: dart:core::@class::double
+            staticType: null
+          type: double
+      rightBracket: >
+    constructorSelector: ConstructorSelector
+      period: .
+      name: SimpleIdentifier
+        token: named
+        staticElement: <null>
+        staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: ParameterMember
+            base: self::@enum::E::@constructor::named::@parameter::a
+            substitution: {T: double}
+          staticType: double
+      rightParenthesis: )
+  constructorElement: ConstructorMember
+    base: self::@enum::E::@constructor::named
+    substitution: {T: double}
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_notGeneric_named() async {
@@ -140,16 +205,31 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: findElement.constructor('named'),
-    );
-
-    assertParameterElement(
-      findNode.integerLiteral('42'),
-      findElement.parameter('a'),
-    );
+    final node = findNode.enumConstantDeclaration('v.');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    constructorSelector: ConstructorSelector
+      period: .
+      name: SimpleIdentifier
+        token: named
+        staticElement: <null>
+        staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: self::@enum::E::@constructor::named::@parameter::a
+          staticType: int
+      rightParenthesis: )
+  constructorElement: self::@enum::E::@constructor::named
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_notGeneric_unnamed() async {
@@ -160,16 +240,25 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: findElement.enum_('E').unnamedConstructor,
-    );
-
-    assertParameterElement(
-      findNode.integerLiteral('42'),
-      findElement.parameter('a'),
-    );
+    final node = findNode.enumConstantDeclaration('v(');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: self::@enum::E::@constructor::•::@parameter::a
+          staticType: int
+      rightParenthesis: )
+  constructorElement: self::@enum::E::@constructor::•
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_notGeneric_unnamed_implicit() async {
@@ -179,11 +268,16 @@
 }
 ''');
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: findElement.enum_('E').unnamedConstructor,
-    );
+    final node = findNode.enumConstantDeclaration('v\n');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  constructorElement: self::@enum::E::@constructor::•
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_unresolved_named() async {
@@ -196,13 +290,31 @@
       error(CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_NAMED, 13, 5),
     ]);
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: null,
-    );
-
-    assertParameterElement(findNode.integerLiteral('42'), null);
+    final node = findNode.enumConstantDeclaration('v.');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    constructorSelector: ConstructorSelector
+      period: .
+      name: SimpleIdentifier
+        token: named
+        staticElement: <null>
+        staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: <null>
+          staticType: null
+      rightParenthesis: )
+  constructorElement: <null>
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_constructor_unresolved_unnamed() async {
@@ -215,13 +327,25 @@
       error(CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_UNNAMED, 11, 1),
     ]);
 
-    assertEnumConstant(
-      findNode.enumConstantDeclaration('v'),
-      element: findElement.field('v'),
-      constructorElement: null,
-    );
-
-    assertParameterElement(findNode.integerLiteral('42'), null);
+    final node = findNode.enumConstantDeclaration('v(');
+    assertResolvedNodeText(node, r'''
+EnumConstantDeclaration
+  name: SimpleIdentifier
+    token: v
+    staticElement: self::@enum::E::@field::v
+    staticType: null
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        IntegerLiteral
+          literal: 42
+          parameter: <null>
+          staticType: null
+      rightParenthesis: )
+  constructorElement: <null>
+  declaredElement: self::@enum::E::@field::v
+''');
   }
 
   test_field() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index 0cb0ce2..8cd9fc4 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -2036,6 +2036,93 @@
 ''');
   }
 
+  test_instanceGetter_nonFunctionType() async {
+    await assertErrorsInCode('''
+abstract class A {
+  List<int> get f;
+}
+
+void foo(A a) {
+  a.f<String>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 61, 1),
+    ]);
+
+    assertResolvedNodeText(findNode.functionReference('f<String>'), r'''
+FunctionReference
+  function: PrefixedIdentifier
+    prefix: SimpleIdentifier
+      token: a
+      staticElement: self::@function::foo::@parameter::a
+      staticType: A
+    period: .
+    identifier: SimpleIdentifier
+      token: f
+      staticElement: self::@class::A::@getter::f
+      staticType: List<int>
+    staticElement: self::@class::A::@getter::f
+    staticType: List<int>
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: String
+          staticElement: dart:core::@class::String
+          staticType: null
+        type: String
+    rightBracket: >
+  staticType: dynamic
+''');
+  }
+
+  test_instanceGetter_nonFunctionType_propertyAccess() async {
+    await assertErrorsInCode('''
+abstract class A {
+  List<int> get f;
+}
+
+void foo(A a) {
+  (a).f<String>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 63, 1),
+    ]);
+
+    assertResolvedNodeText(findNode.functionReference('f<String>'), r'''
+FunctionReference
+  function: PropertyAccess
+    target: ParenthesizedExpression
+      leftParenthesis: (
+      expression: SimpleIdentifier
+        token: a
+        staticElement: self::@function::foo::@parameter::a
+        staticType: A
+      rightParenthesis: )
+      staticType: A
+    operator: .
+    propertyName: SimpleIdentifier
+      token: f
+      staticElement: self::@class::A::@getter::f
+      staticType: List<int>
+    staticType: List<int>
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: String
+          staticElement: dart:core::@class::String
+          staticType: null
+        type: String
+    rightBracket: >
+  staticType: dynamic
+''');
+  }
+
   test_instanceMethod() async {
     await assertNoErrorsInCode('''
 class A {
@@ -2214,7 +2301,7 @@
   }
 
   test_instanceMethod_explicitReceiver_getter_wrongNumberOfTypeArguments() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 class A {
   int get foo => 0;
 }
@@ -2223,7 +2310,10 @@
   // Extra `()` to force reading the type.
   ((a).foo<double>);
 }
-''');
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 97, 3),
+    ]);
 
     var reference = findNode.functionReference('foo<double>');
     assertResolvedNodeText(reference, r'''
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index 2c998d6..d1babc1 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -2,7 +2,6 @@
 // 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:analyzer/dart/ast/ast.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'context_collection_resolution.dart';
@@ -71,8 +70,6 @@
 }
 ''');
 
-    var indexElement = findElement.method('[]');
-
     var indexExpression = findNode.index('a[0]');
     assertResolvedNodeText(indexExpression, r'''
 IndexExpression
@@ -89,10 +86,6 @@
   staticElement: self::@class::A::@method::[]
   staticType: bool
 ''');
-    assertParameterElement(
-      indexExpression.index,
-      indexElement.parameters[0],
-    );
   }
 
   test_read_cascade_nullShorting() async {
@@ -146,8 +139,6 @@
 }
 ''');
 
-    var indexElement = findElement.method('[]');
-
     var indexExpression = findNode.index('a[0]');
     assertResolvedNodeText(indexExpression, r'''
 IndexExpression
@@ -168,13 +159,6 @@
     substitution: {T: double}
   staticType: double
 ''');
-    assertParameterElement(
-      indexExpression.index,
-      elementMatcher(
-        indexElement.parameters[0],
-        substitution: {'T': 'double'},
-      ),
-    );
   }
 
   test_read_nullable() async {
@@ -218,16 +202,7 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-    var numPlusElement = numElement.getMethod('+')!;
-
-    var indexExpression = findNode.index('a[0]');
-    assertParameterElement(
-      indexExpression.index,
-      indexEqElement.parameters[0],
-    );
-
-    var assignment = indexExpression.parent as AssignmentExpression;
+    var assignment = findNode.assignment('a[0]');
     assertResolvedNodeText(assignment, r'''
 AssignmentExpression
   leftHandSide: IndexExpression
@@ -255,11 +230,6 @@
   staticElement: dart:core::@class::num::@method::+
   staticType: double
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      numPlusElement.parameters[0],
-    );
   }
 
   test_readWrite_assignment_generic() async {
@@ -274,19 +244,7 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-    var doublePlusElement = doubleElement.getMethod('+')!;
-
-    var indexExpression = findNode.index('a[0]');
-    assertParameterElement(
-      indexExpression.index,
-      elementMatcher(
-        indexEqElement.parameters[0],
-        substitution: {'T': 'double'},
-      ),
-    );
-
-    var assignment = indexExpression.parent as AssignmentExpression;
+    var assignment = findNode.assignment('a[0]');
 
     assertResolvedNodeText(assignment, r'''
 AssignmentExpression
@@ -321,11 +279,6 @@
   staticElement: dart:core::@class::double::@method::+
   staticType: double
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      doublePlusElement.parameters[0],
-    );
   }
 
   test_readWrite_nullable() async {
@@ -340,16 +293,7 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-    var numPlusElement = numElement.getMethod('+')!;
-
-    var indexExpression = findNode.index('a?[0]');
-    assertParameterElement(
-      indexExpression.index,
-      indexEqElement.parameters[0],
-    );
-
-    var assignment = indexExpression.parent as AssignmentExpression;
+    var assignment = findNode.assignment('a?[0]');
 
     assertResolvedNodeText(assignment, r'''
 AssignmentExpression
@@ -378,11 +322,6 @@
   staticElement: dart:core::@class::num::@method::+
   staticType: double?
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      numPlusElement.parameters[0],
-    );
   }
 
   test_write() async {
@@ -396,15 +335,7 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-
-    var indexExpression = findNode.index('a[0]');
-    assertParameterElement(
-      indexExpression.index,
-      indexEqElement.parameters[0],
-    );
-
-    var assignment = indexExpression.parent as AssignmentExpression;
+    var assignment = findNode.assignment('a[0]');
 
     assertResolvedNodeText(assignment, r'''
 AssignmentExpression
@@ -433,11 +364,6 @@
   staticElement: <null>
   staticType: double
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      indexEqElement.parameters[1],
-    );
   }
 
   test_write_cascade_nullShorting() async {
@@ -520,17 +446,6 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-
-    var indexExpression = findNode.index('a[0]');
-    assertParameterElement(
-      indexExpression.index,
-      elementMatcher(
-        indexEqElement.parameters[0],
-        substitution: {'T': 'double'},
-      ),
-    );
-
     var assignment = findNode.assignment('a[0]');
 
     assertResolvedNodeText(assignment, r'''
@@ -566,14 +481,6 @@
   staticElement: <null>
   staticType: double
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      elementMatcher(
-        indexEqElement.parameters[1],
-        substitution: {'T': 'double'},
-      ),
-    );
   }
 
   test_write_nullable() async {
@@ -587,14 +494,6 @@
 }
 ''');
 
-    var indexEqElement = findElement.method('[]=');
-
-    var indexExpression = findNode.index('a?[0]');
-    assertParameterElement(
-      indexExpression.index,
-      indexEqElement.parameters[0],
-    );
-
     var assignment = findNode.assignment('a?[0]');
 
     assertResolvedNodeText(assignment, r'''
@@ -624,10 +523,5 @@
   staticElement: <null>
   staticType: double?
 ''');
-
-    assertParameterElement(
-      assignment.rightHandSide,
-      indexEqElement.parameters[1],
-    );
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 4ea37fe..8504247 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -697,24 +697,6 @@
     rightParenthesis: )
   staticType: X
 ''');
-
-    var g1 = findNode.methodInvocation('g1()');
-    assertType(g1, 'A');
-    assertParameterElement(g1, findElement.parameter('a'));
-
-    var g2 = findNode.methodInvocation('g2()');
-    assertType(g2, 'B');
-    assertParameterElement(g2, findElement.parameter('b'));
-
-    var named_g3 = findNode.namedExpression('c: g3()');
-    assertType(named_g3.expression, 'C?');
-    assertParameterElement(named_g3, findElement.parameter('c'));
-    assertNamedParameterRef('c:', 'c');
-
-    var named_g4 = findNode.namedExpression('d: g4()');
-    assertType(named_g4.expression, 'D?');
-    assertParameterElement(named_g4, findElement.parameter('d'));
-    assertNamedParameterRef('d:', 'd');
   }
 
   test_typeAlias_generic_class_generic_named_infer_all() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 25e09df..af87e20 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -744,18 +744,6 @@
   staticInvokeType: void Function(A, B, {C? c, D? d})
   staticType: void
 ''');
-
-    var g1 = findNode.methodInvocation('g1()');
-    assertParameterElement(g1, findElement.parameter('a'));
-
-    var g2 = findNode.methodInvocation('g2()');
-    assertParameterElement(g2, findElement.parameter('b'));
-
-    var named_g3 = findNode.namedExpression('c: g3()');
-    assertParameterElement(named_g3, findElement.parameter('c'));
-
-    var named_g4 = findNode.namedExpression('d: g4()');
-    assertParameterElement(named_g4, findElement.parameter('d'));
   }
 
   test_nullShorting_cascade_firstMethodInvocation() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index b6d8a5b..d80f3d2 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -214,15 +214,6 @@
     expect(element.enclosingElement, expectedEnclosing);
   }
 
-  void assertEnumConstant(
-    EnumConstantDeclaration node, {
-    required FieldElement element,
-    required Object? constructorElement,
-  }) {
-    assertElement(node.declaredElement, element);
-    assertElement(node.constructorElement, constructorElement);
-  }
-
   Future<void> assertErrorsInCode(
       String code, List<ExpectedError> expectedErrors) async {
     addTestFile(code);
@@ -386,12 +377,6 @@
     assertSubstitution(actual.substitution, expectedSubstitution);
   }
 
-  void assertNamedParameterRef(String search, String name) {
-    var ref = findNode.simple(search);
-    assertElement(ref, findElement.parameter(name));
-    assertTypeNull(ref);
-  }
-
   void assertNamedType(
       NamedType node, Element? expectedElement, String? expectedType,
       {Element? expectedPrefix}) {
@@ -435,13 +420,6 @@
     assertErrorsInResult(const []);
   }
 
-  void assertParameterElement(
-    Expression expression,
-    Object? elementOrMatcher,
-  ) {
-    assertElement(expression.staticParameterElement, elementOrMatcher);
-  }
-
   void assertParameterElementType(FormalParameter node, String expected) {
     var parameterElement = node.declaredElement!;
     assertType(parameterElement.type, expected);
diff --git a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
index aa935ec..0481b30 100644
--- a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
@@ -15,6 +15,42 @@
 
 @reflectiveTest
 class BodyMayCompleteNormallyTest extends PubPackageResolutionTest {
+  test_enum_method_nonNullable_blockBody_switchStatement_notNullable_exhaustive() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  a;
+
+  static const b = 0;
+  static final c = 0;
+
+  int get value {
+    switch (this) {
+      case a:
+        return 0;
+    }
+  }
+}
+''');
+  }
+
+  test_enum_method_nonNullable_blockBody_switchStatement_notNullable_notExhaustive() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, b;
+
+  int get value {
+    switch (this) {
+      case a:
+        return 0;
+    }
+  }
+}
+''', [
+      error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 28, 5),
+      error(StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, 40, 13),
+    ]);
+  }
+
   test_factoryConstructor_named_blockBody() async {
     await assertErrorsInCode(r'''
 class A {
@@ -92,6 +128,24 @@
 ''');
   }
 
+  test_function_nonNullable_blockBody_switchStatement_notNullable_exhaustive_enhanced() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  a;
+
+  static const b = 0;
+  static final c = 0;
+}
+
+int f(E e) {
+  switch (e) {
+    case E.a:
+      return 0;
+  }
+}
+''');
+  }
+
   test_function_nonNullable_blockBody_switchStatement_notNullable_exhaustive_parenthesis() async {
     await assertNoErrorsInCode(r'''
 enum Foo { a, b }
@@ -123,6 +177,26 @@
     ]);
   }
 
+  test_function_nonNullable_blockBody_switchStatement_notNullable_notExhaustive_enhanced() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, b;
+
+  static const c = 0;
+}
+
+int f(E e) {
+  switch (e) {
+    case E.a:
+      return 0;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 47, 1),
+      error(StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, 58, 10),
+    ]);
+  }
+
   test_function_nonNullable_blockBody_switchStatement_nullable_exhaustive_default() async {
     await assertNoErrorsInCode(r'''
 enum Foo { a, b }
diff --git a/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart b/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
index 7ea8972..dd74912 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
@@ -17,6 +17,25 @@
 @reflectiveTest
 class MissingEnumConstantInSwitchTest extends PubPackageResolutionTest
     with MissingEnumConstantInSwitchTestCases {
+  test_all_enhanced() async {
+    await assertNoErrorsInCode('''
+enum E {
+  one, two;
+
+  static const x = 0;
+}
+
+void f(E e) {
+  switch (e) {
+    case E.one:
+      break;
+    case E.two:
+      break;
+  }
+}
+''');
+  }
+
   test_nullable() async {
     await assertErrorsInCode('''
 enum E { one, two }
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 787c85b..f7f158b 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -376,6 +376,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
+        _writeElement('constructorElement', node.constructorElement);
         _writeElement('declaredElement', node.declaredElement);
       }
     });
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 6608327..9ad3e64 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1484,6 +1484,26 @@
   }
 
   @override
+  bool importsLibrary(Uri uri) {
+    // Self-reference.
+    if (resolvedUnit.libraryElement.source.uri == uri) return false;
+
+    // Existing import.
+    for (var import in resolvedUnit.libraryElement.imports) {
+      var importedLibrary = import.importedLibrary;
+      if (importedLibrary != null && importedLibrary.source.uri == uri) {
+        return true;
+      }
+    }
+
+    // Queued change.
+    var importChange = (libraryChangeBuilder ?? this).librariesToImport[uri];
+    if (importChange != null) return true;
+
+    return false;
+  }
+
+  @override
   void replaceTypeWithFuture(
       TypeAnnotation? typeAnnotation, TypeProvider typeProvider) {
     //
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 4eababe..2082af0 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -359,6 +359,10 @@
   /// If there is no existing import, a new import is added.
   ImportLibraryElementResult importLibraryElement(Uri uri);
 
+  /// Return `true` if the given library [uri] is already imported or will be
+  /// imported by a scheduled edit.
+  bool importsLibrary(Uri uri);
+
   /// Optionally create an edit to replace the given [typeAnnotation] with the
   /// type `Future` (with the given type annotation as the type argument). The
   /// [typeProvider] is used to check the current type, because if it is already
diff --git a/pkg/compiler/lib/src/common/elements.dart b/pkg/compiler/lib/src/common/elements.dart
index 47d4930..4da2a43 100644
--- a/pkg/compiler/lib/src/common/elements.dart
+++ b/pkg/compiler/lib/src/common/elements.dart
@@ -1399,6 +1399,14 @@
   /// Returns the metadata constants declared on [member].
   Iterable<ConstantValue> getMemberMetadata(MemberEntity member,
       {bool includeParameterMetadata = false});
+
+  /// `true` if field is the backing field for a `late` or `late final` instance
+  /// field.
+  bool isLateBackingField(FieldEntity field);
+
+  /// `true` if field is the backing field for a `late final` instance field. If
+  /// this is true, so is [isLateBackingField].
+  bool isLateFinalBackingField(FieldEntity field);
 }
 
 abstract class JElementEnvironment extends ElementEnvironment {
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index bf08b01..8f700cb 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -484,14 +484,11 @@
       _globalInferenceResults.resultOfParameter(e);
 
   FieldInfo visitField(ir.Field field, {FieldEntity fieldEntity}) {
-    FieldInfo info = FieldInfo(
-        name: field.name.text,
-        type: field.type.toStringInternal(),
-        inferredType: null,
-        code: null,
-        outputUnit: null,
-        isConst: field.isConst,
-        size: null);
+    FieldInfo info = FieldInfo.fromKernel(
+      name: field.name.text,
+      type: field.type.toStringInternal(),
+      isConst: field.isConst,
+    );
     state.entityToInfo[fieldEntity] = info;
 
     if (compiler.options.experimentCallInstrumentation) {
@@ -575,7 +572,7 @@
     bool isGetter = parent is ir.Procedure && parent.isGetter;
     bool isSetter = parent is ir.Procedure && parent.isSetter;
     int kind;
-    if (isTopLevel) {
+    if (isStaticMember || isTopLevel) {
       kind = FunctionInfo.TOP_LEVEL_FUNCTION_KIND;
     } else if (isMethod) {
       kind = FunctionInfo.METHOD_FUNCTION_KIND;
@@ -623,18 +620,13 @@
         : ir.Nullability.nonNullable;
     final functionType = function.computeFunctionType(nullability);
 
-    FunctionInfo info = FunctionInfo(
+    FunctionInfo info = FunctionInfo.fromKernel(
         name: name,
         functionKind: kind,
         modifiers: modifiers,
         returnType: function.returnType.toStringInternal(),
-        inferredReturnType: null,
         parameters: parameters,
-        sideEffects: null,
-        inlinedCount: null,
-        code: null,
-        type: functionType.toStringInternal(),
-        outputUnit: null);
+        type: functionType.toStringInternal());
     state.entityToInfo[functionEntity] = info;
 
     if (function.parent is ir.Member)
@@ -672,8 +664,7 @@
         }
       });
       final closureClassEntity = closureEntity.enclosingClass;
-      final closureInfo = ClosureInfo(
-          name: value.disambiguatedName, outputUnit: null, size: null);
+      final closureInfo = ClosureInfo.fromKernel(name: value.disambiguatedName);
       state.entityToInfo[closureClassEntity] = closureInfo;
 
       FunctionEntity callMethod = closedWorld.elementEnvironment
@@ -1282,23 +1273,23 @@
         ..run();
 
       dumpInfoState = buildDumpInfoDataNew(closedWorld, kernelInfoCollector);
+      TreeShakingInfoVisitor().filter(dumpInfoState.info);
+
       if (useBinaryFormat) {
         dumpInfoBinary(dumpInfoState.info);
       } else {
-        dumpInfoJson(dumpInfoState.info, filterTreeshaken: true);
+        dumpInfoJson(dumpInfoState.info);
       }
     });
     return dumpInfoState;
   }
 
-  void dumpInfoJson(AllInfo data, {bool filterTreeshaken = false}) {
+  void dumpInfoJson(AllInfo data) {
     StringBuffer jsonBuffer = StringBuffer();
     JsonEncoder encoder = const JsonEncoder.withIndent('  ');
     ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
         StringConversionSink.fromStringSink(jsonBuffer));
-    sink.add(AllInfoJsonCodec(
-            isBackwardCompatible: true, filterTreeshaken: filterTreeshaken)
-        .encode(data));
+    sink.add(AllInfoJsonCodec(isBackwardCompatible: true).encode(data));
     final name = (compiler.options.outputUri?.pathSegments?.last ?? 'out');
     compiler.outputProvider
         .createOutputSink(name, 'info.json', api.OutputType.dumpInfo)
@@ -1311,11 +1302,9 @@
     });
   }
 
-  void dumpInfoBinary(AllInfo data, {bool filterTreeshaken = false}) {
+  void dumpInfoBinary(AllInfo data) {
     final name = (compiler.options.outputUri?.pathSegments?.last ?? 'out') +
         ".info.data";
-    // TODO(markzipan): Plumb [filterTreeshaken] through
-    // [BinaryOutputSinkAdapter].
     Sink<List<int>> sink = BinaryOutputSinkAdapter(compiler.outputProvider
         .createBinarySink(compiler.options.outputUri.resolve(name)));
     dump_info.encode(data, sink);
@@ -1495,8 +1484,6 @@
   @override
   String get text => '$_text';
   int get length => end - start;
-
-  _CodeData() : super.empty();
 }
 
 /// Holds dump-info's mutable state.
@@ -1605,3 +1592,97 @@
   }
   return parts.reversed.join('_');
 }
+
+/// Filters dead code from Dart2JS [Info] trees.
+class TreeShakingInfoVisitor extends InfoVisitor<void> {
+  List<T> filterDeadInfo<T extends Info>(List<T> infos) {
+    return infos
+        .where((info) => info.treeShakenStatus == TreeShakenStatus.Live)
+        .toList();
+  }
+
+  void filter(AllInfo info) {
+    info.program = info.program;
+    info.libraries = filterDeadInfo<LibraryInfo>(info.libraries);
+    info.functions = filterDeadInfo<FunctionInfo>(info.functions);
+    info.typedefs = filterDeadInfo<TypedefInfo>(info.typedefs);
+    info.typedefs = filterDeadInfo<TypedefInfo>(info.typedefs);
+    info.classes = filterDeadInfo<ClassInfo>(info.classes);
+    info.classTypes = filterDeadInfo<ClassTypeInfo>(info.classTypes);
+    info.fields = filterDeadInfo<FieldInfo>(info.fields);
+    info.constants = filterDeadInfo<ConstantInfo>(info.constants);
+    info.closures = filterDeadInfo<ClosureInfo>(info.closures);
+    info.outputUnits = filterDeadInfo<OutputUnitInfo>(info.outputUnits);
+    info.deferredFiles = info.deferredFiles;
+    // TODO(markzipan): 'dependencies' is always empty. Revisit this if/when
+    // this holds meaningful information.
+    info.dependencies = info.dependencies;
+    info.accept(this);
+  }
+
+  @override
+  visitAll(AllInfo info) {
+    info.libraries = filterDeadInfo<LibraryInfo>(info.libraries);
+    info.constants = filterDeadInfo<ConstantInfo>(info.constants);
+
+    info.libraries.forEach(visitLibrary);
+    info.constants.forEach(visitConstant);
+  }
+
+  @override
+  visitProgram(ProgramInfo info) {}
+
+  @override
+  visitLibrary(LibraryInfo info) {
+    info.topLevelFunctions =
+        filterDeadInfo<FunctionInfo>(info.topLevelFunctions);
+    info.topLevelVariables = filterDeadInfo<FieldInfo>(info.topLevelVariables);
+    info.classes = filterDeadInfo<ClassInfo>(info.classes);
+    info.classTypes = filterDeadInfo<ClassTypeInfo>(info.classTypes);
+    info.typedefs = filterDeadInfo<TypedefInfo>(info.typedefs);
+
+    info.topLevelFunctions.forEach(visitFunction);
+    info.topLevelVariables.forEach(visitField);
+    info.classes.forEach(visitClass);
+    info.classTypes.forEach(visitClassType);
+    info.typedefs.forEach(visitTypedef);
+  }
+
+  @override
+  visitClass(ClassInfo info) {
+    info.functions = filterDeadInfo<FunctionInfo>(info.functions);
+    info.fields = filterDeadInfo<FieldInfo>(info.fields);
+
+    info.functions.forEach(visitFunction);
+    info.fields.forEach(visitField);
+  }
+
+  @override
+  visitClassType(ClassTypeInfo info) {}
+
+  @override
+  visitField(FieldInfo info) {
+    info.closures = filterDeadInfo<ClosureInfo>(info.closures);
+
+    info.closures.forEach(visitClosure);
+  }
+
+  @override
+  visitConstant(ConstantInfo info) {}
+
+  @override
+  visitFunction(FunctionInfo info) {
+    info.closures = filterDeadInfo<ClosureInfo>(info.closures);
+
+    info.closures.forEach(visitClosure);
+  }
+
+  @override
+  visitTypedef(TypedefInfo info) {}
+  @override
+  visitOutput(OutputUnitInfo info) {}
+  @override
+  visitClosure(ClosureInfo info) {
+    visitFunction(info.function);
+  }
+}
diff --git a/pkg/compiler/lib/src/ir/element_map.dart b/pkg/compiler/lib/src/ir/element_map.dart
index 51f1e6f..6b61632 100644
--- a/pkg/compiler/lib/src/ir/element_map.dart
+++ b/pkg/compiler/lib/src/ir/element_map.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
 
@@ -54,16 +52,16 @@
   /// [node].
   TypeVariableEntity getTypeVariable(ir.TypeParameter node);
 
-  CommonElements /*!*/ get commonElements;
+  CommonElements get commonElements;
   DiagnosticReporter get reporter;
   ir.CoreTypes get coreTypes;
-  InterfaceType /*!*/ getThisType(covariant ClassEntity cls);
-  InterfaceType getSuperType(covariant ClassEntity cls);
+  InterfaceType getThisType(covariant ClassEntity cls);
+  InterfaceType? getSuperType(covariant ClassEntity cls);
   OrderedTypeSet getOrderedTypeSet(covariant ClassEntity cls);
   Iterable<InterfaceType> getInterfaces(covariant ClassEntity cls);
-  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls);
+  InterfaceType? asInstanceOf(InterfaceType type, ClassEntity cls);
   DartType substByContext(DartType type, InterfaceType context);
-  FunctionType getCallType(InterfaceType type);
+  FunctionType? getCallType(InterfaceType type);
   int getHierarchyDepth(covariant ClassEntity cls);
   DartType getTypeVariableBound(IndexedTypeVariable typeVariable);
   List<Variance> getTypeVariableVariances(covariant ClassEntity cls);
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 44c6a41..4076ead 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -297,6 +297,10 @@
           if (canBeElided(kField)) {
             fieldData[jField] = const FieldAnalysisData(isElided: true);
           }
+          // TODO(sra): Because we skip the logic below for fields annotated
+          // with `@pragma('dart2js:noElision')`, fields retained due to the
+          // pragma are not deduced to be `isInitializedInAllocator` even when
+          // they could be.
         } else {
           if (data.initialValue != null) {
             ConstantValue initialValue;
@@ -367,6 +371,8 @@
             if (!isTooComplex && initialValue != null) {
               ConstantValue value = map.toBackendConstant(initialValue);
               bool isEffectivelyConstant = false;
+              bool isAssignedOnce = false;
+              bool isLateBackingField = false;
               bool isInitializedInAllocator = false;
               assert(value != null);
               if (!memberUsage.hasWrite && canBeElided(kField)) {
@@ -377,11 +383,17 @@
                 // allocators when it does cause allocators to deoptimized
                 // because of deferred loading.
                 isInitializedInAllocator = true;
+                isLateBackingField =
+                    closedWorld.elementEnvironment.isLateBackingField(kField);
+                isAssignedOnce = closedWorld.elementEnvironment
+                    .isLateFinalBackingField(kField);
               }
               fieldData[jField] = FieldAnalysisData(
                   initialValue: value,
                   isEffectivelyFinal: isEffectivelyConstant,
                   isElided: isEffectivelyConstant,
+                  isAssignedOnce: isAssignedOnce,
+                  isLateBackingField: isLateBackingField,
                   isInitializedInAllocator: isInitializedInAllocator);
             }
           }
@@ -581,6 +593,15 @@
   final bool isEffectivelyFinal;
   final bool isElided;
 
+  /// The field has two values, an initial value and a subsequent value. The
+  /// backing field for a `late final` instance field has this property.
+  // TODO(sra): It might be possible to infer other fields have this property,
+  // e.g. manual lazy fields initialized via `??=` to a not-null value.
+  final bool isAssignedOnce;
+
+  /// The field is a backing field for a late instance field.
+  final bool isLateBackingField;
+
   /// If `true` the field is not effectively constant but the initializer can be
   /// generated eagerly without the need for lazy initialization wrapper.
   final bool isEager;
@@ -597,6 +618,8 @@
       this.isInitializedInAllocator = false,
       this.isEffectivelyFinal = false,
       this.isElided = false,
+      this.isAssignedOnce = false,
+      this.isLateBackingField = false,
       this.isEager = false,
       this.eagerCreationIndex = null,
       this.eagerFieldDependenciesForTesting = null});
@@ -608,6 +631,8 @@
     bool isInitializedInAllocator = source.readBool();
     bool isEffectivelyFinal = source.readBool();
     bool isElided = source.readBool();
+    bool isAssignedOnce = source.readBool();
+    bool isLateBackingField = source.readBool();
     bool isEager = source.readBool();
     int eagerCreationIndex = source.readIntOrNull();
     List<FieldEntity> eagerFieldDependencies =
@@ -618,6 +643,8 @@
         isInitializedInAllocator: isInitializedInAllocator,
         isEffectivelyFinal: isEffectivelyFinal,
         isElided: isElided,
+        isAssignedOnce: isAssignedOnce,
+        isLateBackingField: isLateBackingField,
         isEager: isEager,
         eagerCreationIndex: eagerCreationIndex,
         eagerFieldDependenciesForTesting: eagerFieldDependencies);
@@ -629,6 +656,8 @@
     sink.writeBool(isInitializedInAllocator);
     sink.writeBool(isEffectivelyFinal);
     sink.writeBool(isElided);
+    sink.writeBool(isAssignedOnce);
+    sink.writeBool(isLateBackingField);
     sink.writeBool(isEager);
     sink.writeIntOrNull(eagerCreationIndex);
     sink.writeMembers(eagerFieldDependenciesForTesting, allowNull: true);
@@ -645,10 +674,14 @@
   ConstantValue get constantValue => isEffectivelyFinal ? initialValue : null;
 
   @override
-  String toString() =>
-      'FieldAnalysisData(initialValue=${initialValue?.toStructuredText(null)},'
+  String toString() => 'FieldAnalysisData('
+      'initialValue=${initialValue?.toStructuredText(null)},'
       'isInitializedInAllocator=$isInitializedInAllocator,'
-      'isEffectivelyFinal=$isEffectivelyFinal,isElided=$isElided,'
-      'isEager=$isEager,eagerCreationIndex=$eagerCreationIndex,'
+      'isEffectivelyFinal=$isEffectivelyFinal,'
+      'isElided=$isElided,'
+      'isAssignedOnce=$isAssignedOnce,'
+      'isLateBackingField=$isLateBackingField,'
+      'isEager=$isEager,'
+      'eagerCreationIndex=$eagerCreationIndex,'
       'eagerFieldDependencies=$eagerFieldDependenciesForTesting)';
 }
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index e2437be..192973e 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -43,6 +43,10 @@
 import '../js_backend/runtime_types_resolution.dart';
 import '../js_model/locals.dart';
 import '../kernel/dart2js_target.dart';
+import '../kernel/transformations/late_lowering.dart' as late_lowering
+    show
+        isBackingFieldForLateInstanceField,
+        isBackingFieldForLateFinalInstanceField;
 import '../native/behavior.dart';
 import '../native/enqueue.dart';
 import '../options.dart';
@@ -778,7 +782,7 @@
   InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
     assert(checkFamily(cls));
     OrderedTypeSet orderedTypeSet = getOrderedTypeSet(type.element);
-    InterfaceType supertype =
+    InterfaceType /*?*/ supertype =
         orderedTypeSet.asInstanceOf(cls, getHierarchyDepth(cls));
     if (supertype != null) {
       supertype = substByContext(supertype, type);
@@ -1341,13 +1345,13 @@
         constructor, KConstructorDataImpl(node, functionNode));
   }
 
-  FunctionEntity getMethodInternal(ir.Procedure node) {
+  FunctionEntity getMethodInternal(ir.Procedure /*!*/ node) {
     // [_getMethodCreate] inserts the created function in [methodMap] so we
     // don't need to use ??= here.
     return methodMap[node] ?? _getMethodCreate(node);
   }
 
-  FunctionEntity _getMethodCreate(ir.Procedure node) {
+  FunctionEntity /*!*/ _getMethodCreate(ir.Procedure node) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
@@ -1415,12 +1419,23 @@
     }
     Name name = getName(node.name);
     bool isStatic = node.isStatic;
+    bool isLateBackingField = false;
+    bool isLateFinalBackingField = false;
+    if (enclosingClass != null && !isStatic) {
+      isLateBackingField =
+          late_lowering.isBackingFieldForLateInstanceField(node);
+      isLateFinalBackingField =
+          late_lowering.isBackingFieldForLateFinalInstanceField(node);
+    }
     IndexedField field = createField(library, enclosingClass, name,
         isStatic: isStatic,
         isAssignable: node.hasSetter,
         isConst: node.isConst);
     return members.register<IndexedField, KFieldData>(
-        field, KFieldDataImpl(node));
+        field,
+        KFieldDataImpl(node,
+            isLateBackingField: isLateBackingField,
+            isLateFinalBackingField: isLateFinalBackingField));
   }
 
   bool checkFamily(Entity entity) {
@@ -1965,6 +1980,20 @@
     } while (isMixinApplication(cls));
     return cls;
   }
+
+  @override
+  bool isLateBackingField(covariant IndexedField field) {
+    assert(elementMap.checkFamily(field));
+    KFieldData fieldData = elementMap.members.getData(field);
+    return fieldData.isLateBackingField;
+  }
+
+  @override
+  bool isLateFinalBackingField(covariant IndexedField field) {
+    assert(elementMap.checkFamily(field));
+    KFieldData fieldData = elementMap.members.getData(field);
+    return fieldData.isLateFinalBackingField;
+  }
 }
 
 class KernelNativeMemberResolver {
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 4611754..398082b 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -776,12 +776,29 @@
 
 abstract class KFieldData extends KMemberData {
   DartType getFieldType(IrToElementMap elementMap);
+
+  /// `true` if this field is the backing field for a `late` or `late final`
+  /// instance field.
+  bool get isLateBackingField;
+
+  /// `true` if this field is the backing field for a `late final` instance
+  /// field.
+  bool get isLateFinalBackingField;
 }
 
 class KFieldDataImpl extends KMemberDataImpl implements KFieldData {
   DartType _type;
 
-  KFieldDataImpl(ir.Field node) : super(node);
+  @override
+  final bool isLateBackingField;
+
+  @override
+  final bool isLateFinalBackingField;
+
+  KFieldDataImpl(ir.Field node,
+      {/*required*/ this.isLateBackingField,
+      /*required*/ this.isLateFinalBackingField})
+      : super(node);
 
   @override
   ir.Field get node => super.node;
diff --git a/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart b/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
index 7711128..1cc5b85 100644
--- a/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
+++ b/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
@@ -20,6 +20,36 @@
   }
 }
 
+const _lateInstanceFieldPrefix = '_#';
+const _lateFinalUninitializedSuffix = '#F';
+const _lateAssignableUninitializedSuffix = '#A';
+const _lateFinalInitializedSuffix = '#FI';
+const _lateAssignableInitializedSuffix = '#AI';
+
+bool _hasFinalSuffix(String name) {
+  return name.endsWith(_lateFinalUninitializedSuffix) ||
+      name.endsWith(_lateFinalInitializedSuffix);
+}
+
+bool _hasAssignableSuffix(String name) {
+  return name.endsWith(_lateAssignableUninitializedSuffix) ||
+      name.endsWith(_lateAssignableInitializedSuffix);
+}
+
+bool isBackingFieldForLateInstanceField(Field field) {
+  assert(!field.isStatic);
+  if (!field.isInternalImplementation) return false;
+  final name = field.name.text;
+  return name.startsWith(_lateInstanceFieldPrefix) &&
+      (_hasFinalSuffix(name) || _hasAssignableSuffix(name));
+}
+
+bool isBackingFieldForLateFinalInstanceField(Field field) {
+  if (!field.isInternalImplementation) return false;
+  final name = field.name.text;
+  return name.startsWith(_lateInstanceFieldPrefix) && _hasFinalSuffix(name);
+}
+
 class LateLowering {
   final CoreTypes _coreTypes;
 
@@ -74,8 +104,18 @@
 
   Name _mangleFieldName(Field field) {
     assert(_shouldLowerInstanceField(field));
+    final prefix = _lateInstanceFieldPrefix;
+    final suffix = field.initializer == null
+        ? field.isFinal
+            ? _lateFinalUninitializedSuffix
+            : _lateAssignableUninitializedSuffix
+        : field.isFinal
+            ? _lateFinalInitializedSuffix
+            : _lateAssignableInitializedSuffix;
+
     Class cls = field.enclosingClass!;
-    return Name('_#${cls.name}#${field.name.text}', field.enclosingLibrary);
+    return Name(
+        '$prefix${cls.name}#${field.name.text}$suffix', field.enclosingLibrary);
   }
 
   ConstructorInvocation _callCellConstructor(Expression name, int fileOffset) =>
diff --git a/pkg/compiler/lib/src/phase/load_kernel.dart b/pkg/compiler/lib/src/phase/load_kernel.dart
index 803c8f9..de39f19 100644
--- a/pkg/compiler/lib/src/phase/load_kernel.dart
+++ b/pkg/compiler/lib/src/phase/load_kernel.dart
@@ -2,10 +2,9 @@
 // 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.
 
-// @dart = 2.10
-
 import 'dart:async';
 
+import 'package:collection/collection.dart';
 import 'package:front_end/src/fasta/kernel/utils.dart';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
@@ -49,7 +48,7 @@
   /// The [Uri] of the root library containing main.
   /// Note: rootLibraryUri will be null for some modules, for example in the
   /// case of dependent libraries processed modularly.
-  final Uri rootLibraryUri;
+  final Uri? rootLibraryUri;
 
   /// Returns the [Uri]s of all libraries that have been loaded that are
   /// reachable from the [rootLibraryUri].
@@ -75,8 +74,8 @@
 }
 
 Library _findEntryLibrary(Component component, Uri entryUri) {
-  var entryLibrary = component.libraries
-      .firstWhere((l) => l.fileUri == entryUri, orElse: () => null);
+  final entryLibrary =
+      component.libraries.firstWhereOrNull((l) => l.fileUri == entryUri);
   if (entryLibrary == null) {
     throw ArgumentError('Entry uri $entryUri not found in dill.');
   }
@@ -84,16 +83,16 @@
 }
 
 ir.Reference _findMainMethod(Library entryLibrary) {
-  var mainMethod = entryLibrary.procedures
-      .firstWhere((p) => p.name.text == 'main', orElse: () => null);
+  var mainMethod =
+      entryLibrary.procedures.firstWhereOrNull((p) => p.name.text == 'main');
 
   // In some cases, a main method is defined in another file, and then
   // exported. In these cases, we search for the main method in
   // [additionalExports].
-  ir.Reference mainMethodReference;
+  ir.Reference? mainMethodReference;
   if (mainMethod == null) {
     mainMethodReference = entryLibrary.additionalExports
-        .firstWhere((p) => p.canonicalName.name == 'main', orElse: () => null);
+        .firstWhereOrNull((p) => p.canonicalName?.name == 'main');
   } else {
     mainMethodReference = mainMethod.reference;
   }
@@ -121,8 +120,8 @@
 }
 
 class _LoadFromKernelResult {
-  final ir.Component component;
-  final Library entryLibrary;
+  final ir.Component? component;
+  final Library? entryLibrary;
   final List<Uri> moduleLibraries;
 
   _LoadFromKernelResult(
@@ -135,8 +134,8 @@
 
 Future<_LoadFromKernelResult> _loadFromKernel(CompilerOptions options,
     api.CompilerInput compilerInput, String targetName) async {
-  Library entryLibrary;
-  var resolvedUri = options.compilationTarget;
+  Library? entryLibrary;
+  var resolvedUri = options.compilationTarget!;
   ir.Component component = ir.Component();
   List<Uri> moduleLibraries = [];
 
@@ -171,24 +170,24 @@
       options.modularMode || options.hasModularAnalysisInputs;
   if (options.platformBinaries != null && !platformBinariesIncluded) {
     var platformUri = options.platformBinaries
-        .resolve(_getPlatformFilename(options, targetName));
+        ?.resolve(_getPlatformFilename(options, targetName));
     // Modular analysis can be run on the sdk by providing directly the
     // path to the platform.dill file. In that case, we do not load the
     // platform file implicitly.
     // TODO(joshualitt): Change how we detect this case so it is less
     // brittle.
-    if (platformUri != resolvedUri) await read(platformUri);
+    if (platformUri != resolvedUri) await read(platformUri!);
   }
 
   // Concatenate dills.
   if (options.dillDependencies != null) {
-    for (Uri dependency in options.dillDependencies) {
+    for (Uri dependency in options.dillDependencies!) {
       await read(dependency);
     }
   }
 
   if (options.entryUri != null) {
-    entryLibrary = _findEntryLibrary(component, options.entryUri);
+    entryLibrary = _findEntryLibrary(component, options.entryUri!);
     var mainMethod = _findMainMethod(entryLibrary);
     component.setMainMethodAndMode(mainMethod, true, component.mode);
   }
@@ -201,7 +200,7 @@
 }
 
 class _LoadFromSourceResult {
-  final ir.Component component;
+  final ir.Component? component;
   final fe.InitializedCompilerState initializedCompilerState;
   final List<Uri> moduleLibraries;
 
@@ -217,7 +216,7 @@
     String targetName) async {
   bool verbose = false;
   bool cfeConstants = options.features.cfeConstants.isEnabled;
-  Map<String, String> environment = cfeConstants ? options.environment : null;
+  Map<String, String>? environment = cfeConstants ? options.environment : null;
   Target target = Dart2jsTarget(targetName, TargetFlags(),
       options: options,
       canPerformGlobalTransforms: true,
@@ -237,7 +236,7 @@
   List<Uri> sources = [];
   if (options.sources != null) {
     isModularCompile = true;
-    sources.addAll(options.sources);
+    sources.addAll(options.sources!);
   } else {
     fe.CompilerOptions feOptions = fe.CompilerOptions()
       ..target = target
@@ -249,22 +248,22 @@
       ..fileSystem = fileSystem
       ..onDiagnostic = onDiagnostic
       ..verbosity = verbosity;
-    Uri resolvedUri = options.compilationTarget;
+    Uri resolvedUri = options.compilationTarget!;
     bool isLegacy =
         await fe.uriUsesLegacyLanguageVersion(resolvedUri, feOptions);
     _inferNullSafetyMode(options, !isLegacy);
-    sources.add(options.compilationTarget);
+    sources.add(options.compilationTarget!);
   }
 
   // If we are performing a modular compile, we expect the platform binary to be
   // supplied along with other dill dependencies.
   List<Uri> dependencies = [];
   if (options.platformBinaries != null && !isModularCompile) {
-    dependencies.add(options.platformBinaries
+    dependencies.add(options.platformBinaries!
         .resolve(_getPlatformFilename(options, targetName)));
   }
   if (options.dillDependencies != null) {
-    dependencies.addAll(options.dillDependencies);
+    dependencies.addAll(options.dillDependencies!);
   }
 
   initializedCompilerState = fe.initializeCompiler(
@@ -279,14 +278,14 @@
           options.useLegacySubtyping ? fe.NnbdMode.Weak : fe.NnbdMode.Strong,
       invocationModes: options.cfeInvocationModes,
       verbosity: verbosity);
-  ir.Component component = await fe.compile(initializedCompilerState, verbose,
+  ir.Component? component = await fe.compile(initializedCompilerState, verbose,
       fileSystem, onDiagnostic, sources, isModularCompile);
   _validateNullSafetyMode(options);
 
   // We have to compute canonical names on the component here to avoid missing
   // canonical names downstream.
   if (isModularCompile) {
-    component.computeCanonicalNames();
+    component?.computeCanonicalNames();
   }
   return _LoadFromSourceResult(
       component, initializedCompilerState, isModularCompile ? sources : []);
@@ -295,11 +294,11 @@
 Output _createOutput(
     CompilerOptions options,
     DiagnosticReporter reporter,
-    Library entryLibrary,
+    Library? entryLibrary,
     ir.Component component,
     List<Uri> moduleLibraries,
     fe.InitializedCompilerState initializedCompilerState) {
-  Uri rootLibraryUri = null;
+  Uri? rootLibraryUri = null;
   Iterable<ir.Library> libraries = component.libraries;
   if (!options.modularMode) {
     // For non-modular builds we should always have a [mainMethod] at this
@@ -317,7 +316,7 @@
     // NOTE: Under some circumstances, the [entryLibrary] exports the
     // [mainMethod] from another library, and thus the [enclosingLibrary] of
     // the [mainMethod] may not be the same as the [entryLibrary].
-    var root = entryLibrary ?? component.mainMethod.enclosingLibrary;
+    var root = entryLibrary ?? component.mainMethod!.enclosingLibrary;
     rootLibraryUri = root.importUri;
 
     // Filter unreachable libraries: [Component] was built by linking in the
@@ -360,15 +359,15 @@
 }
 
 /// Loads an entire Kernel [Component] from a file on disk.
-Future<Output> run(Input input) async {
+Future<Output?> run(Input input) async {
   CompilerOptions options = input.options;
   api.CompilerInput compilerInput = input.compilerInput;
   DiagnosticReporter reporter = input.reporter;
 
   String targetName = options.compileForServer ? "dart2js_server" : "dart2js";
 
-  Library entryLibrary;
-  ir.Component component;
+  Library? entryLibrary;
+  ir.Component? component;
   List<Uri> moduleLibraries = const [];
   fe.InitializedCompilerState initializedCompilerState =
       input.initializedCompilerState;
diff --git a/pkg/compiler/lib/src/serialization/indexed_sink_source.dart b/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
index 82db5e0..32f46e5 100644
--- a/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
+++ b/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
@@ -5,23 +5,43 @@
 import 'data_sink.dart';
 import 'data_source.dart';
 
+abstract class IndexedSource<E> {
+  E? read(E readValue());
+
+  /// Reshapes the cache to a [Map<E, int>] using [_getValue] if provided or
+  /// leaving the cache entry as is otherwise.
+  Map<T, int> reshape<T>([T Function(E? value)? getValue]);
+}
+
+abstract class IndexedSink<E> {
+  void write(E value, void writeValue(E value));
+}
+
 /// Data sink helper that canonicalizes [E?] values using indices.
-class IndexedSink<E extends Object> {
+///
+/// Writes a list index in place of already indexed values. This list index
+/// is the order in which we discover the indexable elements. On deserialization
+/// the indexable elements but be visited in the same order they were seen here
+/// so that the indices are maintained. Since the read order is assumed to be
+/// consistent, the actual data is written at the first occurrence of the
+/// indexable element.
+class OrderedIndexedSink<E extends Object> implements IndexedSink<E> {
   final DataSink _sink;
   final Map<E?, int> cache;
 
-  IndexedSink._(this._sink, this.cache);
+  OrderedIndexedSink._(this._sink, this.cache);
 
-  factory IndexedSink(DataSink sink, {Map<E?, int>? cache}) {
+  factory OrderedIndexedSink(DataSink sink, {Map<E?, int>? cache}) {
     // [cache] slot 0 is pre-allocated to `null`.
     cache ??= {null: 0};
-    return IndexedSink._(sink, cache);
+    return OrderedIndexedSink._(sink, cache);
   }
 
   /// Write a reference to [value] to the data sink.
   ///
   /// If [value] has not been canonicalized yet, [writeValue] is called to
   /// serialize the [value] itself.
+  @override
   void write(E? value, void writeValue(E value)) {
     const int pending = -1;
     int? index = cache[value];
@@ -40,22 +60,29 @@
 }
 
 /// Data source helper reads canonicalized [E?] values through indices.
-class IndexedSource<E extends Object> {
+///
+/// Reads indexable elements treating their read order as their index. Since the
+/// read order is consistent with the write order, when a new index is
+/// discovered we assume the data is written immediately after. Subsequent
+/// occurrences of that index then refer to the same value. Indices will appear
+/// in ascending order.
+class OrderedIndexedSource<E extends Object> implements IndexedSource<E> {
   final DataSource _source;
   final List<E?> cache;
 
-  IndexedSource._(this._source, this.cache);
+  OrderedIndexedSource._(this._source, this.cache);
 
-  factory IndexedSource(DataSource source, {List<E?>? cache}) {
+  factory OrderedIndexedSource(DataSource source, {List<E?>? cache}) {
     // [cache] slot 0 is pre-allocated to `null`.
     cache ??= [null];
-    return IndexedSource._(source, cache);
+    return OrderedIndexedSource._(source, cache);
   }
 
   /// Reads a reference to an [E] value from the data source.
   ///
   /// If the value hasn't yet been read, [readValue] is called to deserialize
   /// the value itself.
+  @override
   E? read(E readValue()) {
     int index = _source.readInt();
     if (index >= cache.length) {
@@ -72,4 +99,14 @@
       return value;
     }
   }
+
+  @override
+  Map<T, int> reshape<T>([T Function(E? value)? getValue]) {
+    var newCache = <T, int>{};
+    for (int i = 0; i < cache.length; i++) {
+      final newKey = getValue == null ? cache[i] as T : getValue(cache[i]);
+      newCache[newKey] = i;
+    }
+    return newCache;
+  }
 }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index d0aa69e..6eca6fd 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -58,32 +58,20 @@
 /// Data class representing cache information for a given [T] which can be
 /// passed from a [DataSourceReader] to other [DataSourceReader]s and [DataSinkWriter]s.
 class DataSourceTypeIndices<E, T> {
-  /// Reshapes a [List<T>] to a [Map<E, int>] using [_getValue].
-  Map<E, int> _reshape() {
-    var cache = <E, int>{};
-    for (int i = 0; i < cacheAsList.length; i++) {
-      cache[_getValue(cacheAsList[i])] = i;
-    }
-    return cache;
-  }
+  Map<E, int> get cache => _cache ??= source.reshape(_getValue);
 
-  Map<E, int> get cache {
-    return _cache ??= _reshape();
-  }
-
-  final List<T> cacheAsList;
-  E Function(T value) _getValue;
+  final E Function(T value) _getValue;
   Map<E, int> _cache;
+  final IndexedSource<T> source;
 
   /// Though [DataSourceTypeIndices] supports two types of caches. If the
-  /// exported indices are imported into a [DataSourceReader] then the [cacheAsList]
+  /// exported indices are imported into a [DataSourceReader] then the [cacheAsMap]
   /// will be used as is. If, however, the exported indices are imported into a
   /// [DataSinkWriter] then we need to reshape the [List<T>] into a [Map<E, int>]
   /// where [E] is either [T] or some value which can be derived from [T] by
   /// [_getValue].
-  DataSourceTypeIndices(this.cacheAsList, [this._getValue]) {
+  DataSourceTypeIndices(this.source, [this._getValue]) {
     assert(_getValue != null || T == E);
-    _getValue ??= (T t) => t as E;
   }
 }
 
diff --git a/pkg/compiler/lib/src/serialization/sink.dart b/pkg/compiler/lib/src/serialization/sink.dart
index 077bfd8..e298ad5 100644
--- a/pkg/compiler/lib/src/serialization/sink.dart
+++ b/pkg/compiler/lib/src/serialization/sink.dart
@@ -49,10 +49,10 @@
 
   IndexedSink<T> _createSink<T>() {
     if (importedIndices == null || !importedIndices.caches.containsKey(T)) {
-      return IndexedSink<T>(this._sinkWriter);
+      return OrderedIndexedSink<T>(this._sinkWriter);
     } else {
       Map<T, int> cacheCopy = Map.from(importedIndices.caches[T].cache);
-      return IndexedSink<T>(this._sinkWriter, cache: cacheCopy);
+      return OrderedIndexedSink<T>(this._sinkWriter, cache: cacheCopy);
     }
   }
 
diff --git a/pkg/compiler/lib/src/serialization/source.dart b/pkg/compiler/lib/src/serialization/source.dart
index 81e477b..af907c4 100644
--- a/pkg/compiler/lib/src/serialization/source.dart
+++ b/pkg/compiler/lib/src/serialization/source.dart
@@ -38,10 +38,11 @@
 
   IndexedSource<T> _createSource<T>() {
     if (importedIndices == null || !importedIndices.caches.containsKey(T)) {
-      return IndexedSource<T>(this._sourceReader);
+      return OrderedIndexedSource<T>(this._sourceReader);
     } else {
-      List<T> cacheCopy = importedIndices.caches[T].cacheAsList.toList();
-      return IndexedSource<T>(this._sourceReader, cache: cacheCopy);
+      final source = importedIndices.caches[T].source as OrderedIndexedSource;
+      List<T> cacheCopy = source.cache.toList();
+      return OrderedIndexedSource<T>(this._sourceReader, cache: cacheCopy);
     }
   }
 
@@ -58,17 +59,17 @@
   /// [DataSinkWriter]s.
   DataSourceIndices exportIndices() {
     var indices = DataSourceIndices();
-    indices.caches[String] = DataSourceTypeIndices(_stringIndex.cache);
-    indices.caches[Uri] = DataSourceTypeIndices(_uriIndex.cache);
-    indices.caches[ImportEntity] = DataSourceTypeIndices(_importIndex.cache);
+    indices.caches[String] = DataSourceTypeIndices(_stringIndex);
+    indices.caches[Uri] = DataSourceTypeIndices(_uriIndex);
+    indices.caches[ImportEntity] = DataSourceTypeIndices(_importIndex);
     // _memberNodeIndex needs two entries depending on if the indices will be
     // consumed by a [DataSource] or [DataSink].
-    indices.caches[MemberData] = DataSourceTypeIndices(_memberNodeIndex.cache);
+    indices.caches[MemberData] = DataSourceTypeIndices(_memberNodeIndex);
     indices.caches[ir.Member] = DataSourceTypeIndices<ir.Member, MemberData>(
-        _memberNodeIndex.cache, (MemberData data) => data?.node);
-    indices.caches[ConstantValue] = DataSourceTypeIndices(_constantIndex.cache);
+        _memberNodeIndex, (MemberData data) => data?.node);
+    indices.caches[ConstantValue] = DataSourceTypeIndices(_constantIndex);
     _generalCaches.forEach((type, indexedSource) {
-      indices.caches[type] = DataSourceTypeIndices(indexedSource.cache);
+      indices.caches[type] = DataSourceTypeIndices(indexedSource);
     });
     return indices;
   }
@@ -182,7 +183,7 @@
   /// not yet been deserialized, [f] is called to deserialize the value itself.
   @override
   E /*?*/ readCachedOrNull<E>(E f()) {
-    IndexedSource source = _generalCaches[E] ??= _createSource<E>();
+    IndexedSource<E> source = _generalCaches[E] ??= _createSource<E>();
     return source.read(f);
   }
 
diff --git a/pkg/compiler/lib/src/ssa/late_field_optimizer.dart b/pkg/compiler/lib/src/ssa/late_field_optimizer.dart
new file mode 100644
index 0000000..3232ee5
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/late_field_optimizer.dart
@@ -0,0 +1,219 @@
+// Copyright (c) 2013, 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.
+
+// @dart = 2.10
+
+import '../elements/entities.dart';
+import '../inferrer/abstract_value_domain.dart';
+import '../js_backend/field_analysis.dart' show JFieldAnalysis;
+import '../world.dart' show JClosedWorld;
+import 'logging.dart';
+import 'nodes.dart';
+import 'optimize.dart' show OptimizationPhase;
+
+/// Optimization phase that tries to eliminate late field checks and memory
+/// loads.
+class SsaLateFieldOptimizer extends HBaseVisitor implements OptimizationPhase {
+  @override
+  final String name = "SsaLateFieldOptimizer";
+
+  final JClosedWorld _closedWorld;
+  final OptimizationTestLog /*?*/ _log;
+
+  final AbstractValueDomain _abstractValueDomain;
+  final JFieldAnalysis _fieldAnalysis;
+
+  SsaLateFieldOptimizer(this._closedWorld, this._log)
+      : _abstractValueDomain = _closedWorld.abstractValueDomain,
+        _fieldAnalysis = _closedWorld.fieldAnalysis;
+
+  @override
+  void visitGraph(HGraph graph) {
+    _log?.instructionHistogram('$name.pre', graph, _summarizeInstruction);
+
+    visitDominatorTree(graph);
+
+    _log?.instructionHistogram('$name.post', graph, _summarizeInstruction);
+  }
+
+  static String /*?*/ _summarizeInstruction(HInstruction node) {
+    if (node is HLateCheck) return '${node.runtimeType}';
+    if (node is HFieldGet) return '${node.runtimeType}';
+    return null;
+  }
+
+  @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
+  void visitBasicBlock(HBasicBlock block) {
+    HInstruction instruction = block.first;
+    while (instruction != null) {
+      HInstruction next = instruction.next;
+      instruction.accept(this);
+      instruction = next;
+    }
+  }
+
+  @override
+  void visitLateReadCheck(HLateReadCheck node) {
+    // The getter for a `late` instance field has a check on the backing field
+    // to ensure that the sentinel value has been overwritten by an initializing
+    // assignment. When the getter is inlined, there is a sequence of loads,
+    // each with a check. `h(g(a.f), g(a.f))` looks like the following, where
+    // `#f` is the backing field for late field `f`.
+    //
+    //     t1 = HFieldGet(a, #f)       {T,sentinel}
+    //     t2 = HLateReadCheck(t1)     {T}
+    //     t9 = g(t2)
+    //     t11 = HFieldGet(a, #f)      {T,sentinel}
+    //     t12 = HLateReadCheck(t11)   {T}
+    //     t19 = g(t12)
+    //     t99 = h(t9, t19)
+    //
+    // The field starts initialized with a sentinel value. HLateReadCheck will
+    // throw if the value is a sentinel.  The backing field is never assigned a
+    // sentinel, so subsequent read checks will always succeed and can be
+    // removed.
+    //
+    // ## `late` fields
+    //
+    // The removal is effected by marking the subsequent loaded values with a
+    // strengthened type that excludes the sentinel, using HTypeKnown. This
+    // makes the sentinel check redundant so it can be removed when it is
+    // visited later in the pass.
+    //
+    // To prevent _uses_ of the loaded values from being moved to before the
+    // check, HTypeKnown is witnessed by (has a dependency on) the original
+    // check. We know the value is not a sentinel only _after_ the check.
+    // (Optimizations preserve the order of loads and stores. It is fine for the
+    // second load to move before the first check provided doing so does not
+    // change the value seen by the second load.)
+    //
+    // After inserting the HTypeKnown.witnessed instruction after each
+    // subsequent load we have:
+    //
+    //     t1 = HFieldGet(a, #f)       {T,sentinel}
+    //     t2 = HLateReadCheck(t1)     {T}
+    //     t9 = g(t2)
+    //     t11 = HFieldGet(a, #f)      {T,sentinel}
+    //     t12 = HTypeKnown(t11, t2)   {T}
+    //     t13 = HLateReadCheck(t12)   {T}
+    //     t19 = g(t13)
+    //     t99 = h(t9, t19)
+    //
+    // The subsequent checks are now redundant, and are visited after the
+    // initial check, so they are cleaned up when visited.
+    //
+    //     t1 = HFieldGet(a, #f)       {T,sentinel}
+    //     t2 = HLateReadCheck(t1)     {T}
+    //     t9 = g(t2)
+    //     t11 = HFieldGet(a, #f)      {T,sentinel}
+    //     t12 = HTypeKnown(t11, t2)   {T}
+    //     t19 = g(t12)
+    //     t99 = h(t9, t19)
+    //
+    // ## `late final` fields
+    //
+    // `late final` fields change value only once from sentinel to final value.
+    // If the read-check passes, the value is the final value, so the subsequent
+    // reads can be replaced by the checked value:
+    //
+    //     t1 = HFieldGet(a, #f)       {T,sentinel}
+    //     t2 = HLateReadCheck(t1)     {T}
+    //     t9 = g(t2)
+    //     t12 = HLateReadCheck(t2)   {T}
+    //     t19 = g(t12)
+    //     t99 = h(t9, t19)
+    //
+    // This leads to back-to-back HLateReadCheck instructions, the second of
+    // which is redundant and is removed:
+    //
+    //     t1 = HFieldGet(a, #f)       {T,sentinel}
+    //     t2 = HLateReadCheck(t1)     {T}
+    //     t9 = g(t2)
+    //     t19 = g(t2)
+    //     t99 = h(t9, t19)
+
+    HInstruction input = node.checkedInput;
+
+    // Cleanup. Remove redundant checks.
+    if (input is HLateReadCheck || node.isRedundant(_closedWorld)) {
+      node.block.rewrite(node, input);
+      node.block.remove(node);
+      return;
+    }
+
+    if (input is HFieldGet) {
+      HInstruction receiver = input.receiver;
+      FieldEntity field = input.element;
+
+      final uses = DominatedUses.of(receiver, node);
+
+      List<HFieldGet> loads = [];
+      for (HInstruction use in uses.instructions) {
+        if (use is HFieldGet && use.element == field) {
+          loads.add(use);
+        }
+      }
+
+      if (loads.isEmpty) return;
+
+      if (_fieldAnalysis.getFieldData(field).isAssignedOnce) {
+        // `late final` backing fields are assigned at most once, so loads can
+        // be replaced with the dominating checked load value.
+        for (final load in loads) {
+          load.block.rewrite(load, node);
+          load.block.remove(load);
+        }
+      } else {
+        for (final load in loads) {
+          final known = HTypeKnown.witnessed(node.instructionType, load, node)
+            ..sourceInformation = node.sourceInformation;
+          load.block.rewrite(load, known);
+          load.block.addAfter(load, known);
+        }
+      }
+    }
+  }
+
+  @override
+  void visitFieldSet(HFieldSet node) {
+    FieldEntity field = node.element;
+    final fieldData = _fieldAnalysis.getFieldData(field);
+    if (!fieldData.isLateBackingField) return;
+
+    // [node] is a store to the backing field for a late instance field. The
+    // stored value cannot be the sentinel value, so future loads of the field
+    // will never be the sentinel value and do not need to be checked.
+    final uses = DominatedUses.of(node.receiver, node, excludeDominator: true);
+
+    List<HFieldGet> loads = [];
+    for (HInstruction use in uses.instructions) {
+      if (use is HFieldGet && use.element == field) {
+        loads.add(use);
+      }
+    }
+
+    if (loads.isEmpty) return;
+
+    if (fieldData.isAssignedOnce) {
+      // [field] is a `late final` field so the stored value is the value of
+      // every subsequent load. Replace loads with the stored value.
+      for (final load in loads) {
+        load.block.rewrite(load, node.value);
+        load.block.remove(load);
+      }
+    } else {
+      // The subsequent loaded value cannot be the sentinel value. Refine the
+      // type of the load which will allow any check on the load to be removed.
+      // There is no need for HTypeKnown.witnessed since it would be an invalid
+      // transformation to move the read before the write.
+      for (final load in loads) {
+        load.instructionType =
+            _abstractValueDomain.excludeLateSentinel(load.instructionType);
+      }
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/ssa/logging.dart b/pkg/compiler/lib/src/ssa/logging.dart
index 2fe3f6f..e9d5467 100644
--- a/pkg/compiler/lib/src/ssa/logging.dart
+++ b/pkg/compiler/lib/src/ssa/logging.dart
@@ -267,6 +267,29 @@
     entries.add(OptimizationLogEntry('PrimitiveCheck', features));
   }
 
+  /// Generates optimization log entries that form a histogram. [summarize]
+  /// projects the instruction to a string that is used as a key for counting
+  /// instructions. [summarize] returns `null` to omit the instruction.
+  void instructionHistogram(
+      String tag, HGraph graph, String /*?*/ Function(HInstruction) summarize) {
+    Map<String, int> histogram = {};
+    for (final block in graph.blocks) {
+      for (HInstruction node = block.first; node != null; node = node.next) {
+        String /*?*/ description = summarize(node);
+        if (description != null) {
+          int count = histogram[description] ?? 0;
+          histogram[description] = count + 1;
+        }
+      }
+    }
+
+    for (final entry in histogram.entries) {
+      Features features = Features();
+      features[entry.key] = '${entry.value}';
+      entries.add(OptimizationLogEntry(tag, features));
+    }
+  }
+
   String getText() {
     return entries.join(',\n');
   }
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 95b6cb9..8fcda3b 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -37,6 +37,7 @@
 import '../world.dart' show JClosedWorld;
 import 'interceptor_simplifier.dart';
 import 'interceptor_finalizer.dart';
+import 'late_field_optimizer.dart';
 import 'logging.dart';
 import 'nodes.dart';
 import 'types.dart';
@@ -122,6 +123,7 @@
         loadElimination = SsaLoadElimination(closedWorld),
         SsaRedundantPhiEliminator(),
         SsaDeadPhiEliminator(),
+        SsaLateFieldOptimizer(closedWorld, log),
         // After GVN and load elimination the same value may be used in code
         // controlled by a test on the value, so redo 'conversion insertion' to
         // learn from the refined type.
@@ -1416,7 +1418,8 @@
 
   @override
   HInstruction visitTypeKnown(HTypeKnown node) {
-    return node.isRedundant(_closedWorld) ? node.checkedInput : node;
+    if (node.isRedundant(_closedWorld)) return node.checkedInput;
+    return node;
   }
 
   @override
diff --git a/pkg/compiler/test/codegen/data/late_field_read_check_optimization.dart b/pkg/compiler/test/codegen/data/late_field_read_check_optimization.dart
new file mode 100644
index 0000000..d721b50
--- /dev/null
+++ b/pkg/compiler/test/codegen/data/late_field_read_check_optimization.dart
@@ -0,0 +1,65 @@
+// 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.
+
+// @dart = 2.17
+
+/*member: main:ignore*/
+void main() {
+  final x1 = XX();
+  x1.foo = 100;
+  x1.bar = 200;
+  x1.useFoo();
+  x1.useBar();
+}
+
+class XX {
+  late int foo;
+  late final int bar;
+
+  @pragma('dart2js:noInline')
+  /*member: XX.useFoo:function() {
+  var t2, t3, t4, t5, _this = this,
+    t1 = _this.__XX_foo_A;
+  if (t1 === $)
+    A.throwLateFieldNI("foo");
+  t2 = _this.effect$0();
+  t3 = _this.__XX_foo_A;
+  t4 = _this.effect$0();
+  t5 = _this.__XX_foo_A;
+  _this.use$8(t1, t1, t2, t3, t3, t4, t5, t5);
+}*/
+  void useFoo() {
+    // There is only one check on `foo` since the first check dominates all the
+    // others.  `foo` is not final, so the field needs to be reloaded after
+    // `effects()`.
+    use(foo, foo, effect(), foo, foo, effect(), foo, foo);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.useBar:function() {
+  var _this = this,
+    t1 = _this.__XX_bar_F;
+  if (t1 === $)
+    A.throwLateFieldNI("bar");
+  _this.use$8(t1, t1, _this.effect$0(), t1, t1, _this.effect$0(), t1, t1);
+}*/
+  void useBar() {
+    // There is only one check on `bar` since the first check dominates all the
+    // others.  Since `bar` is final, the checked value is reused.
+    use(bar, bar, effect(), bar, bar, effect(), bar, bar);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.use:ignore*/
+  void use(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
+    print([a1, a2, a3, a4, a5, a6, a7, a8]);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.effect:ignore*/
+  int effect() {
+    foo++;
+    return 0;
+  }
+}
diff --git a/pkg/compiler/test/dump_info/data/marker.options b/pkg/compiler/test/dump_info/data/marker.options
index 620f7d3..e127a4b 100644
--- a/pkg/compiler/test/dump_info/data/marker.options
+++ b/pkg/compiler/test/dump_info/data/marker.options
@@ -1,2 +1,3 @@
 spec=pkg/compiler/test/dump_info/dump_info_test.dart
+canary=pkg/compiler/test/dump_info/dump_info_new_regression_test.dart
 
diff --git a/pkg/compiler/test/dump_info/dump_info_new_regression_test.dart b/pkg/compiler/test/dump_info/dump_info_new_regression_test.dart
new file mode 100644
index 0000000..afcd05d
--- /dev/null
+++ b/pkg/compiler/test/dump_info/dump_info_new_regression_test.dart
@@ -0,0 +1,349 @@
+// 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.
+
+// Tests that Kernel Dump Info matches the original Dump Info's output after
+// filtering non-live blocks.
+
+// @dart = 2.7
+
+import 'dart:convert';
+import 'dart:io';
+import 'package:_fe_analyzer_shared/src/testing/features.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/dump_info.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_world.dart';
+import 'package:dart2js_info/info.dart' as info;
+import 'package:dart2js_info/json_info_codec.dart' as info;
+import 'package:kernel/ast.dart' as ir;
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+
+final JsonEncoder encoder = const JsonEncoder();
+final JsonEncoder indentedEncoder = const JsonEncoder.withIndent('  ');
+
+String jsonEncode(Map object, {bool indent = true}) {
+  var jsonEncoder = indent ? indentedEncoder : encoder;
+  var transformedObject = transformJsonObjectForComparison(object);
+  // Filter block comments since they interfere with ID test comments.
+  var json = jsonEncoder
+      .convert(transformedObject)
+      .replaceAll('/*', '')
+      .replaceAll('*/', '');
+  return json;
+}
+
+/// Transforms a new DumpInfo or old DumpInfo object into a format that allows
+/// for easier comparison.
+Map transformJsonObjectForComparison(Map object) {
+  Map newObject = {};
+  object.forEach((key, value) {
+    if (value == null) {
+      newObject[key] = value;
+      return;
+    }
+
+    dynamic newValue = value;
+    // Ignore type fields since K-World and J-World type strings are
+    // non-trivially different (though semantically identical).
+    if (key == 'type' || key == 'returnType') {
+      return;
+    }
+
+    // Ignore sizes for output units, as these deviate by some constant when
+    // `--canary` is enabled.
+    if (object['kind'] == 'outputUnit' && key == 'size') {
+      return;
+    }
+
+    // Remove disambiguation portions of names. E.g., name%N -> name.
+    if (key == 'id' || key == 'name' || key == 'function') {
+      newValue = value.replaceAll(RegExp(r'%\d+'), '');
+    } else if (key == 'children') {
+      List values = object[key];
+      newValue =
+          values.map((name) => name.replaceAll(RegExp(r'%\d+'), '')).toList();
+    }
+
+    newObject[key] = newValue;
+  });
+  return newObject;
+}
+
+Map filteredJsonObject(Map object, Set<String> filteredFields) {
+  Map filteredObject = {};
+  object.forEach((key, value) {
+    if (filteredFields.contains(key)) return;
+    filteredObject[key] = value;
+  });
+  return filteredObject;
+}
+
+void main(List<String> args) {
+  // Do not allow these tests to regenerate annotations.
+  final filteredArgs =
+      args.where((arg) => arg != '--g' && arg != '--generate').toList();
+
+  asyncTest(() async {
+    Directory dataDir = Directory.fromUri(Platform.script.resolve('data'));
+    print('Testing output of dump-info');
+    print('==================================================================');
+    await checkTests(dataDir, const DumpInfoDataComputer(),
+        args: filteredArgs,
+        testedConfigs: allSpecConfigs,
+        options: ['--dump-info', '--canary', '--enable-asserts']);
+  });
+}
+
+class Tags {
+  static const String library = 'library';
+  static const String clazz = 'class';
+  static const String classType = 'classType';
+  static const String closure = 'closure';
+  static const String function = 'function';
+  static const String typeDef = 'typedef';
+  static const String field = 'field';
+  static const String constant = 'constant';
+  static const String holding = 'holding';
+  static const String dependencies = 'dependencies';
+  static const String outputUnits = 'outputUnits';
+  static const String deferredFiles = 'deferredFiles';
+}
+
+class DumpInfoDataComputer extends DataComputer<Features> {
+  const DumpInfoDataComputer();
+
+  static const String wildcard = '%';
+
+  @override
+  void computeLibraryData(Compiler compiler, LibraryEntity library,
+      Map<Id, ActualData<Features>> actualMap,
+      {bool verbose}) {
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
+    DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
+    TreeShakingInfoVisitor().filter(dumpInfoState.info);
+
+    final features = Features();
+    final libraryInfo = dumpInfoState.entityToInfo[library];
+    if (libraryInfo == null) return;
+
+    features.addElement(
+        Tags.library, jsonEncode(libraryInfo.accept(converter)));
+
+    // Store program-wide information on the main library.
+    final name = '${library.canonicalUri.pathSegments.last}';
+    if (name.startsWith('main')) {
+      for (final constantInfo in dumpInfoState.info.constants) {
+        features.addElement(
+            Tags.constant, jsonEncode(constantInfo.accept(converter)));
+      }
+      features.addElement(
+          Tags.dependencies, jsonEncode(dumpInfoState.info.dependencies));
+      for (final outputUnit in dumpInfoState.info.outputUnits) {
+        var outputUnitJsonObject = outputUnit.accept(converter);
+        // Remove the size from output units due to high noise ratio.
+        outputUnitJsonObject =
+            filteredJsonObject(outputUnitJsonObject, {'size'});
+        features.addElement(Tags.outputUnits, jsonEncode(outputUnitJsonObject));
+      }
+      features.addElement(
+          Tags.deferredFiles, jsonEncode(dumpInfoState.info.deferredFiles));
+    }
+
+    final id = LibraryId(library.canonicalUri);
+    actualMap[id] =
+        ActualData<Features>(id, features, library.canonicalUri, -1, library);
+  }
+
+  @override
+  void computeClassData(Compiler compiler, ClassEntity cls,
+      Map<Id, ActualData<Features>> actualMap,
+      {bool verbose: false}) {
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
+    DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
+    TreeShakingInfoVisitor().filter(dumpInfoState.info);
+
+    final features = Features();
+    final classInfo = dumpInfoState.entityToInfo[cls];
+    if (classInfo == null) return;
+
+    features.addElement(Tags.clazz, jsonEncode(classInfo.accept(converter)));
+    final classTypeInfos =
+        dumpInfoState.info.classTypes.where((i) => i.name == classInfo.name);
+    assert(
+        classTypeInfos.length < 2,
+        'Ambiguous class type info resolution. '
+        'Expected 0 or 1 elements, found: $classTypeInfos');
+    if (classTypeInfos.length == 1) {
+      features.addElement(
+          Tags.classType, jsonEncode(classTypeInfos.first.accept(converter)));
+    }
+
+    JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+    JsToElementMap elementMap = closedWorld.elementMap;
+    ir.Class node = elementMap.getClassDefinition(cls).node;
+    ClassId id = ClassId(node.name);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    actualMap[id] = ActualData<Features>(id, features,
+        nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, cls);
+  }
+
+  @override
+  void computeMemberData(Compiler compiler, MemberEntity member,
+      Map<Id, ActualData<Features>> actualMap,
+      {bool verbose: false}) {
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
+    DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
+    TreeShakingInfoVisitor().filter(dumpInfoState.info);
+
+    final features = Features();
+    final functionInfo = dumpInfoState.entityToInfo[member];
+    if (functionInfo == null ||
+        functionInfo.treeShakenStatus != info.TreeShakenStatus.Live) return;
+
+    if (functionInfo is info.FunctionInfo) {
+      features.addElement(
+          Tags.function, jsonEncode(functionInfo.accept(converter)));
+      for (final use in functionInfo.uses) {
+        features.addElement(Tags.holding,
+            jsonEncode(converter.visitDependencyInfo(use), indent: false));
+      }
+      for (final closure in functionInfo.closures) {
+        features.addElement(
+            Tags.closure, jsonEncode(closure.accept(converter)));
+      }
+    }
+
+    if (functionInfo is info.FieldInfo) {
+      features.addElement(
+          Tags.function, jsonEncode(functionInfo.accept(converter)));
+      for (final use in functionInfo.uses) {
+        features.addElement(Tags.holding,
+            jsonEncode(converter.visitDependencyInfo(use), indent: false));
+      }
+      for (final closure in functionInfo.closures) {
+        features.addElement(
+            Tags.closure, jsonEncode(closure.accept(converter)));
+      }
+    }
+
+    JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+    JsToElementMap elementMap = closedWorld.elementMap;
+    ir.Member node = elementMap.getMemberDefinition(member).node;
+    Id id = computeMemberId(node);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    actualMap[id] = ActualData<Features>(id, features,
+        nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
+  }
+
+  @override
+  DataInterpreter<Features> get dataValidator =>
+      const JsonFeaturesDataInterpreter(wildcard: wildcard);
+}
+
+/// Feature interpreter for Features with Json values.
+///
+/// The data annotation reader conserves whitespace visually while ignoring
+/// them during comparison.
+class JsonFeaturesDataInterpreter implements DataInterpreter<Features> {
+  final String wildcard;
+  const JsonFeaturesDataInterpreter({this.wildcard});
+
+  @override
+  String isAsExpected(Features actualFeatures, String expectedData) {
+    if (wildcard != null && expectedData == wildcard) {
+      return null;
+    } else if (expectedData == '') {
+      return actualFeatures.isNotEmpty ? "Expected empty data." : null;
+    } else {
+      List<String> errorsFound = [];
+      Features expectedFeatures = Features.fromText(expectedData);
+      Set<String> validatedFeatures = Set<String>();
+      expectedFeatures.forEach((String key, Object expectedValue) {
+        validatedFeatures.add(key);
+        Object actualValue = actualFeatures[key];
+        if (!actualFeatures.containsKey(key)) {
+          errorsFound.add('No data found for $key');
+        } else if (expectedValue == '') {
+          if (actualValue != '') {
+            errorsFound.add('Non-empty data found for $key');
+          }
+        } else if (wildcard != null && expectedValue == wildcard) {
+          return;
+        } else if (expectedValue is List) {
+          if (actualValue is List) {
+            List actualList = actualValue.toList();
+            for (Object expectedObject in expectedValue) {
+              String expectedText =
+                  jsonEncode(jsonDecode(expectedObject), indent: false);
+              bool matchFound = false;
+              if (wildcard != null && expectedText.endsWith(wildcard)) {
+                // Wildcard matcher.
+                String prefix =
+                    expectedText.substring(0, expectedText.indexOf(wildcard));
+                List matches = [];
+                for (Object actualObject in actualList) {
+                  final formattedActualObject =
+                      jsonEncode(jsonDecode(actualObject), indent: false);
+                  if (formattedActualObject.startsWith(prefix)) {
+                    matches.add(actualObject);
+                    matchFound = true;
+                  }
+                }
+                for (Object match in matches) {
+                  actualList.remove(match);
+                }
+              } else {
+                for (Object actualObject in actualList) {
+                  final formattedActualObject =
+                      jsonEncode(jsonDecode(actualObject), indent: false);
+                  if (expectedText == formattedActualObject) {
+                    actualList.remove(actualObject);
+                    matchFound = true;
+                    break;
+                  }
+                }
+              }
+              if (!matchFound) {
+                errorsFound.add("No match found for $key=[$expectedText]");
+              }
+            }
+            if (actualList.isNotEmpty) {
+              errorsFound
+                  .add("Extra data found $key=[${actualList.join(',')}]");
+            }
+          } else {
+            errorsFound.add("List data expected for $key: "
+                "expected '$expectedValue', found '${actualValue}'");
+          }
+        } else if (expectedValue != actualValue) {
+          errorsFound.add("Mismatch for $key: expected '$expectedValue', "
+              "found '${actualValue}'");
+        }
+      });
+      actualFeatures.forEach((String key, Object value) {
+        if (!validatedFeatures.contains(key)) {
+          if (value == '') {
+            errorsFound.add("Extra data found '$key'");
+          } else {
+            errorsFound.add("Extra data found $key=$value");
+          }
+        }
+      });
+      return errorsFound.isNotEmpty ? errorsFound.join('\n ') : null;
+    }
+  }
+
+  @override
+  String getText(Features actualData, [String indentation]) {
+    return actualData.getText(indentation);
+  }
+
+  @override
+  bool isEmpty(Features actualData) {
+    return actualData == null || actualData.isEmpty;
+  }
+}
diff --git a/pkg/compiler/test/dump_info/dump_info_test.dart b/pkg/compiler/test/dump_info/dump_info_test.dart
index e04902f..14b711e 100644
--- a/pkg/compiler/test/dump_info/dump_info_test.dart
+++ b/pkg/compiler/test/dump_info/dump_info_test.dart
@@ -73,8 +73,7 @@
   void computeLibraryData(Compiler compiler, LibraryEntity library,
       Map<Id, ActualData<Features>> actualMap,
       {bool verbose}) {
-    final converter = info.AllInfoToJsonConverter(
-        isBackwardCompatible: true, filterTreeshaken: false);
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
     DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
 
     final features = Features();
@@ -115,8 +114,7 @@
   void computeClassData(Compiler compiler, ClassEntity cls,
       Map<Id, ActualData<Features>> actualMap,
       {bool verbose: false}) {
-    final converter = info.AllInfoToJsonConverter(
-        isBackwardCompatible: true, filterTreeshaken: false);
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
     DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
 
     final features = Features();
@@ -148,8 +146,7 @@
   void computeMemberData(Compiler compiler, MemberEntity member,
       Map<Id, ActualData<Features>> actualMap,
       {bool verbose: false}) {
-    final converter = info.AllInfoToJsonConverter(
-        isBackwardCompatible: true, filterTreeshaken: false);
+    final converter = info.AllInfoToJsonConverter(isBackwardCompatible: true);
     DumpInfoStateData dumpInfoState = compiler.dumpInfoStateForTesting;
 
     final features = Features();
diff --git a/pkg/compiler/test/inference/data/late_field.dart b/pkg/compiler/test/inference/data/late_field.dart
index 678b890..2038243 100644
--- a/pkg/compiler/test/inference/data/late_field.dart
+++ b/pkg/compiler/test/inference/data/late_field.dart
@@ -6,7 +6,7 @@
 
 /*member: Foo.:[exact=Foo]*/
 class Foo {
-  /*member: Foo._#Foo#x:[sentinel|exact=JSUInt31]*/
+  /*member: Foo._#Foo#x#AI:[sentinel|exact=JSUInt31]*/
   /*member: Foo.x:[exact=JSUInt31]*/
   late int /*[exact=Foo]*/ /*update: [exact=Foo]*/ x = 42;
 }
diff --git a/pkg/compiler/test/optimization/data/late_fields.dart b/pkg/compiler/test/optimization/data/late_fields.dart
new file mode 100644
index 0000000..9f35319
--- /dev/null
+++ b/pkg/compiler/test/optimization/data/late_fields.dart
@@ -0,0 +1,71 @@
+// 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.
+
+// @dart = 2.17
+
+/*member: main:**/
+void main() {
+  final x1 = XX();
+  x1.assignUseBar();
+  x1.assignUseFoo();
+  x1.useBar();
+  x1.useFoo();
+}
+
+class XX {
+  late int foo;
+  late final int bar;
+
+  @pragma('dart2js:noInline')
+  /*member: XX.useFoo:
+      SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
+      SsaLateFieldOptimizer.post=[HFieldGet=3,HLateReadCheck=1],
+  */
+  void useFoo() {
+    use(foo, foo, effect(), foo, foo, effect(), foo, foo);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.useBar:
+      SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
+      SsaLateFieldOptimizer.post=[HFieldGet=1,HLateReadCheck=1],
+  */
+  void useBar() {
+    use(bar, bar, effect(), bar, bar, effect(), bar, bar);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.assignUseFoo:
+      SsaLateFieldOptimizer.pre=[HFieldGet=3,HLateReadCheck=3],
+      SsaLateFieldOptimizer.post=[HFieldGet=3],
+  */
+  void assignUseFoo() {
+    foo = 200;
+    use(effect(), foo, effect(), foo, foo, effect(), foo, foo);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.assignUseBar:
+      SsaLateFieldOptimizer.pre=
+          [HFieldGet=4,HLateReadCheck=3,HLateWriteOnceCheck=1],
+      SsaLateFieldOptimizer.post=[HFieldGet=1,HLateWriteOnceCheck=1],
+  */
+  void assignUseBar() {
+    bar = 100;
+    use(effect(), bar, effect(), bar, bar, effect(), bar, bar);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.use:**/
+  void use(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
+    print([a1, a2, a3, a4, a5, a6, a7, a8]);
+  }
+
+  @pragma('dart2js:noInline')
+  /*member: XX.effect:**/
+  int effect() {
+    foo++;
+    return 0;
+  }
+}
diff --git a/pkg/compiler/test/optimization/optimization_test.dart b/pkg/compiler/test/optimization/optimization_test.dart
index e8c1972..0efa7ae 100644
--- a/pkg/compiler/test/optimization/optimization_test.dart
+++ b/pkg/compiler/test/optimization/optimization_test.dart
@@ -8,7 +8,6 @@
 import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/closure.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
@@ -26,7 +25,7 @@
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     bool strict = args.contains('-s');
     await checkTests(dataDir, new OptimizationDataComputer(strict: strict),
-        options: [Flags.disableInlining], args: args);
+        options: [], args: args);
   });
 }
 
diff --git a/pkg/dart2js_info/lib/info.dart b/pkg/dart2js_info/lib/info.dart
index ef0c1a5..48ae501 100644
--- a/pkg/dart2js_info/lib/info.dart
+++ b/pkg/dart2js_info/lib/info.dart
@@ -79,36 +79,36 @@
   ProgramInfo? program;
 
   /// Information about each library processed by the compiler.
-  final List<LibraryInfo> libraries = <LibraryInfo>[];
+  List<LibraryInfo> libraries = <LibraryInfo>[];
 
   /// Information about each function (includes methods and getters in any
   /// library)
-  final List<FunctionInfo> functions = <FunctionInfo>[];
+  List<FunctionInfo> functions = <FunctionInfo>[];
 
   /// Information about type defs in the program.
-  final List<TypedefInfo> typedefs = <TypedefInfo>[];
+  List<TypedefInfo> typedefs = <TypedefInfo>[];
 
   /// Information about each class (in any library).
-  final List<ClassInfo> classes = <ClassInfo>[];
+  List<ClassInfo> classes = <ClassInfo>[];
 
   /// Information about each class type (in any library).
-  final List<ClassTypeInfo> classTypes = <ClassTypeInfo>[];
+  List<ClassTypeInfo> classTypes = <ClassTypeInfo>[];
 
   /// Information about fields (in any class).
-  final List<FieldInfo> fields = <FieldInfo>[];
+  List<FieldInfo> fields = <FieldInfo>[];
 
   /// Information about constants anywhere in the program.
   // TODO(sigmund): expand docs about canonicalization. We don't put these
   // inside library because a single constant can be used in more than one lib,
   // and we'll include it only once in the output.
-  final List<ConstantInfo> constants = <ConstantInfo>[];
+  List<ConstantInfo> constants = <ConstantInfo>[];
 
   /// Information about closures anywhere in the program.
-  final List<ClosureInfo> closures = <ClosureInfo>[];
+  List<ClosureInfo> closures = <ClosureInfo>[];
 
   /// Information about output units (should be just one entry if not using
   /// deferred loading).
-  final List<OutputUnitInfo> outputUnits = <OutputUnitInfo>[];
+  List<OutputUnitInfo> outputUnits = <OutputUnitInfo>[];
 
   /// Details about all deferred imports and what files would be loaded when the
   /// import is resolved.
@@ -189,19 +189,19 @@
   late final Uri uri;
 
   /// Top level functions defined within the library.
-  final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[];
+  List<FunctionInfo> topLevelFunctions = <FunctionInfo>[];
 
   /// Top level fields defined within the library.
-  final List<FieldInfo> topLevelVariables = <FieldInfo>[];
+  List<FieldInfo> topLevelVariables = <FieldInfo>[];
 
   /// Classes defined within the library.
-  final List<ClassInfo> classes = <ClassInfo>[];
+  List<ClassInfo> classes = <ClassInfo>[];
 
   /// Class types defined within the library.
-  final List<ClassTypeInfo> classTypes = <ClassTypeInfo>[];
+  List<ClassTypeInfo> classTypes = <ClassTypeInfo>[];
 
   /// Typedefs defined within the library.
-  final List<TypedefInfo> typedefs = <TypedefInfo>[];
+  List<TypedefInfo> typedefs = <TypedefInfo>[];
 
   // TODO(sigmund): add here a list of parts. That can help us improve how we
   // encode source-span information in metrics (rather than include the uri on
@@ -248,12 +248,12 @@
 
   // TODO(sigmund): split static vs instance vs closures
   /// Functions (static or instance) defined in the class.
-  final List<FunctionInfo> functions = <FunctionInfo>[];
+  List<FunctionInfo> functions = <FunctionInfo>[];
 
   /// Fields defined in the class.
   // TODO(sigmund): currently appears to only be populated with instance fields,
   // but this should be fixed.
-  final List<FieldInfo> fields = <FieldInfo>[];
+  List<FieldInfo> fields = <FieldInfo>[];
 
   ClassInfo(
       {required String name,
@@ -262,6 +262,9 @@
       int size = 0})
       : super(InfoKind.clazz, name, outputUnit, size, null);
 
+  ClassInfo.fromKernel({required String name, required this.isAbstract})
+      : super(InfoKind.clazz, name, null, 0, null);
+
   ClassInfo.internal() : super.internal(InfoKind.clazz);
 
   @override
@@ -287,10 +290,10 @@
 /// file of [BasicInfo.outputUnit].
 class CodeSpan {
   /// Start offset in the generated file.
-  late final int start;
+  int? start;
 
   /// end offset in the generated file.
-  late final int end;
+  int? end;
 
   /// The actual code (optional, blank when using a compact representation of
   /// the encoding).
@@ -325,7 +328,7 @@
   late final String inferredType;
 
   /// Nested closures seen in the field initializer.
-  late final List<ClosureInfo> closures;
+  late List<ClosureInfo> closures;
 
   /// The actual generated code for the field.
   late final List<CodeSpan> code;
@@ -347,6 +350,13 @@
       required this.isConst})
       : super(InfoKind.field, name, outputUnit, size, coverageId);
 
+  FieldInfo.fromKernel(
+      {required String name,
+      String? coverageId,
+      required this.type,
+      required this.isConst})
+      : super(InfoKind.field, name, null, 0, coverageId);
+
   FieldInfo.internal() : super.internal(InfoKind.field);
 
   @override
@@ -381,7 +391,7 @@
   late final FunctionModifiers modifiers;
 
   /// Nested closures that appear within the body of this function.
-  late final List<ClosureInfo> closures;
+  late List<ClosureInfo> closures;
 
   /// The type of this function.
   late final String type;
@@ -421,6 +431,16 @@
       required this.code})
       : super(InfoKind.function, name, outputUnit, size, coverageId);
 
+  FunctionInfo.fromKernel(
+      {required String name,
+      String? coverageId,
+      required this.functionKind,
+      required this.modifiers,
+      required this.type,
+      required this.returnType,
+      required this.parameters})
+      : super(InfoKind.function, name, null, 0, coverageId);
+
   FunctionInfo.internal() : super.internal(InfoKind.function);
 
   @override
@@ -435,6 +455,9 @@
   ClosureInfo({required String name, OutputUnitInfo? outputUnit, int size = 0})
       : super(InfoKind.closure, name, outputUnit, size, null);
 
+  ClosureInfo.fromKernel({required String name})
+      : super(InfoKind.closure, name, null, 0, null);
+
   ClosureInfo.internal() : super.internal(InfoKind.closure);
 
   @override
diff --git a/pkg/dart2js_info/lib/json_info_codec.dart b/pkg/dart2js_info/lib/json_info_codec.dart
index 16dd5c4..65b18a3 100644
--- a/pkg/dart2js_info/lib/json_info_codec.dart
+++ b/pkg/dart2js_info/lib/json_info_codec.dart
@@ -343,13 +343,10 @@
   /// Whether to generate json compatible with format 5.1
   final bool isBackwardCompatible;
 
-  /// Whether to filter all treeshaken elements.
-  final bool filterTreeshaken;
   final Map<Info, Id> ids = HashMap<Info, Id>();
   final Set<String> usedIds = <String>{};
 
-  AllInfoToJsonConverter(
-      {this.isBackwardCompatible = false, this.filterTreeshaken = false});
+  AllInfoToJsonConverter({this.isBackwardCompatible = false});
 
   Id idFor(Info info) {
     var serializedId = ids[info];
@@ -392,12 +389,6 @@
     // Using SplayTree to maintain a consistent order of keys
     var map = SplayTreeMap<String, Map>(compareNatural);
     for (var info in infos) {
-      if (info is BasicInfo) {
-        if (filterTreeshaken &&
-            info.treeShakenStatus != TreeShakenStatus.Live) {
-          continue;
-        }
-      }
       map[idFor(info).id] = info.accept(this);
     }
     return map;
@@ -622,12 +613,7 @@
 
   List<String> _toSortedSerializedIds(
           Iterable<Info> infos, Id Function(Info) getId) =>
-      infos
-          .where((i) =>
-              !filterTreeshaken || i.treeShakenStatus == TreeShakenStatus.Live)
-          .map((i) => getId(i).serializedId)
-          .toList()
-        ..sort(compareNatural);
+      infos.map((i) => getId(i).serializedId).toList()..sort(compareNatural);
 }
 
 class AllInfoJsonCodec extends Codec<AllInfo, Map> {
@@ -636,11 +622,9 @@
   @override
   final Converter<Map, AllInfo> decoder = JsonToAllInfoConverter();
 
-  AllInfoJsonCodec(
-      {bool isBackwardCompatible = false, bool filterTreeshaken = false})
-      : encoder = AllInfoToJsonConverter(
-            isBackwardCompatible: isBackwardCompatible,
-            filterTreeshaken: filterTreeshaken);
+  AllInfoJsonCodec({bool isBackwardCompatible = false})
+      : encoder =
+            AllInfoToJsonConverter(isBackwardCompatible: isBackwardCompatible);
 }
 
 class Id {
diff --git a/pkg/dart2wasm/bin/run_wasm.js b/pkg/dart2wasm/bin/run_wasm.js
index 9aeb626..5e6dcb9 100644
--- a/pkg/dart2wasm/bin/run_wasm.js
+++ b/pkg/dart2wasm/bin/run_wasm.js
@@ -143,18 +143,13 @@
     callMethodVarArgs: function(object, name, args) {
         return object[name].apply(object, args);
     },
-    callConstructorVarArgs: function(object, name, args) {
-        // Gets a constructor property at object[name], and apply bind to the
-        // constructor. We pass `null` as the first argument to `bind.apply`
-        // because this is `bind`'s unused context argument(`new` will
-        // explicitly create a new context).
-        var constructor = object[name];
+    callConstructorVarArgs: function(constructor, args) {
+        // Apply bind to the constructor. We pass `null` as the first argument
+        // to `bind.apply` because this is `bind`'s unused context
+        // argument(`new` will explicitly create a new context).
         var factoryFunction = constructor.bind.apply(constructor, [null, ...args]);
         return new factoryFunction();
     },
-    eval: function(string) {
-        eval(string);
-    }
 };
 
 function instantiate(filename, imports) {
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index fb69fc5..bf65127 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -55,6 +55,11 @@
   final Map<LabeledStatement, w.Label> labels = {};
   final Map<SwitchCase, w.Label> switchLabels = {};
 
+  /// Maps a switch statement to the information used when doing a backward
+  /// jump to one of the cases in the switch statement
+  final Map<SwitchStatement, SwitchBackwardJumpInfo> switchBackwardJumpInfos =
+      {};
+
   /// Create a code generator for a member or one of its lambdas.
   ///
   /// The [paramLocals] and [returnLabel] parameters can be used to generate
@@ -883,47 +888,72 @@
             e is ConstantExpression &&
                 (e.constant is C || e.constant is NullConstant));
 
-    // Identify kind of switch
-    w.ValueType valueType;
+    // Identify kind of switch. One of `nullableType` or `nonNullableType` will
+    // be the type for Wasm local that holds the switch value.
     w.ValueType nullableType;
+    w.ValueType nonNullableType;
     void Function() compare;
     if (check<BoolLiteral, BoolConstant>()) {
       // bool switch
-      valueType = w.NumType.i32;
+      nonNullableType = w.NumType.i32;
       nullableType =
           translator.classInfo[translator.boxedBoolClass]!.nullableType;
       compare = () => b.i32_eq();
     } else if (check<IntLiteral, IntConstant>()) {
       // int switch
-      valueType = w.NumType.i64;
+      nonNullableType = w.NumType.i64;
       nullableType =
           translator.classInfo[translator.boxedIntClass]!.nullableType;
       compare = () => b.i64_eq();
     } else if (check<StringLiteral, StringConstant>()) {
       // String switch
-      valueType =
+      nonNullableType =
           translator.classInfo[translator.stringBaseClass]!.nonNullableType;
-      nullableType = valueType.withNullability(true);
+      nullableType = nonNullableType.withNullability(true);
       compare = () => _call(translator.stringEquals.reference);
     } else {
       // Object switch
       assert(check<InvalidExpression, InstanceConstant>());
-      valueType = w.RefType.eq(nullable: false);
+      nonNullableType = w.RefType.eq(nullable: false);
       nullableType = w.RefType.eq(nullable: true);
       compare = () => b.ref_eq();
     }
-    w.Local valueLocal = addLocal(valueType);
+
+    bool isNullable = dartTypeOf(node.expression).isPotentiallyNullable;
+
+    // When the type is nullable we use two variables: one for the nullable
+    // value, one after the null check, with non-nullable type.
+    w.Local switchValueNonNullableLocal = addLocal(nonNullableType);
+    w.Local? switchValueNullableLocal =
+        isNullable ? addLocal(nullableType) : null;
+
+    // Initialize switch value local
+    wrap(node.expression, isNullable ? nullableType : nonNullableType);
+    b.local_set(
+        isNullable ? switchValueNullableLocal! : switchValueNonNullableLocal);
 
     // Special cases
     SwitchCase? defaultCase = node.cases
         .cast<SwitchCase?>()
         .firstWhere((c) => c!.isDefault, orElse: () => null);
+
     SwitchCase? nullCase = node.cases.cast<SwitchCase?>().firstWhere(
         (c) => c!.expressions.any((e) =>
             e is NullLiteral ||
             e is ConstantExpression && e.constant is NullConstant),
         orElse: () => null);
 
+    // Create `loop` for backward jumps
+    w.Label loopLabel = b.loop();
+
+    // Set `switchValueLocal` for backward jumps
+    w.Local switchValueLocal =
+        isNullable ? switchValueNullableLocal! : switchValueNonNullableLocal;
+
+    // Add backward jump info
+    switchBackwardJumpInfos[node] =
+        SwitchBackwardJumpInfo(switchValueLocal, loopLabel);
+
     // Set up blocks, in reverse order of cases so they end in forward order
     w.Label doneLabel = b.block();
     for (SwitchCase c in node.cases.reversed) {
@@ -931,22 +961,18 @@
     }
 
     // Compute value and handle null
-    bool isNullable = dartTypeOf(node.expression).isPotentiallyNullable;
     if (isNullable) {
       w.Label nullLabel = nullCase != null
           ? switchLabels[nullCase]!
           : defaultCase != null
               ? switchLabels[defaultCase]!
               : doneLabel;
-      wrap(node.expression, nullableType);
+      b.local_get(switchValueNullableLocal!);
       b.br_on_null(nullLabel);
       translator.convertType(
-          function, nullableType.withNullability(false), valueType);
-    } else {
-      assert(nullCase == null);
-      wrap(node.expression, valueType);
+          function, nullableType.withNullability(false), nonNullableType);
+      b.local_set(switchValueNonNullableLocal);
     }
-    b.local_set(valueLocal);
 
     // Compare against all case values
     for (SwitchCase c in node.cases) {
@@ -955,26 +981,50 @@
             exp is ConstantExpression && exp.constant is NullConstant) {
           // Null already checked, skip
         } else {
-          wrap(exp, valueType);
-          b.local_get(valueLocal);
-          translator.convertType(function, valueLocal.type, valueType);
+          wrap(exp, nonNullableType);
+          b.local_get(switchValueNonNullableLocal);
+          translator.convertType(
+              function, switchValueNonNullableLocal.type, nonNullableType);
           compare();
           b.br_if(switchLabels[c]!);
         }
       }
     }
-    w.Label defaultLabel =
-        defaultCase != null ? switchLabels[defaultCase]! : doneLabel;
-    b.br(defaultLabel);
+
+    // No explicit cases matched
+    if (node.isExplicitlyExhaustive) {
+      b.unreachable();
+    } else {
+      w.Label defaultLabel =
+          defaultCase != null ? switchLabels[defaultCase]! : doneLabel;
+      b.br(defaultLabel);
+    }
 
     // Emit case bodies
     for (SwitchCase c in node.cases) {
-      switchLabels.remove(c);
       b.end();
+      // Remove backward jump target from forward jump labels
+      switchLabels.remove(c);
+
+      // Create a `loop` in default case to allow backward jumps to it
+      if (c.isDefault) {
+        switchBackwardJumpInfos[node]!.defaultLoopLabel = b.loop();
+      }
+
       c.body.accept(this);
+
+      if (c.isDefault) {
+        b.end(); // defaultLoopLabel
+      }
+
       b.br(doneLabel);
     }
-    b.end();
+    b.end(); // doneLabel
+    b.end(); // loopLabel
+
+    // Remove backward jump info
+    final removed = switchBackwardJumpInfos.remove(node);
+    assert(removed != null);
   }
 
   @override
@@ -983,7 +1033,24 @@
     if (label != null) {
       b.br(label);
     } else {
-      throw "Not supported: Backward jump to switch case at ${node.location}";
+      // Backward jump. Find the case literal in jump target, set the switched
+      // values to the jump target's value, and loop.
+      final SwitchCase targetSwitchCase = node.target;
+      final SwitchStatement targetSwitch =
+          targetSwitchCase.parent! as SwitchStatement;
+      final SwitchBackwardJumpInfo targetInfo =
+          switchBackwardJumpInfos[targetSwitch]!;
+      if (targetSwitchCase.expressions.isEmpty) {
+        // Default case
+        assert(targetSwitchCase.isDefault);
+        b.br(targetInfo.defaultLoopLabel!);
+        return;
+      }
+      final Expression targetValue =
+          targetSwitchCase.expressions[0]; // pick any of the values
+      wrap(targetValue, targetInfo.switchValueLocal.type);
+      b.local_set(targetInfo.switchValueLocal);
+      b.br(targetInfo.loopLabel);
     }
   }
 
@@ -2079,3 +2146,31 @@
 
   TryBlockFinalizer(this.label);
 }
+
+/// Holds information of a switch statement, to be used when doing a backward
+/// jump to it
+class SwitchBackwardJumpInfo {
+  /// Wasm local for the value of the switched expression. For example, in a
+  /// `switch` like:
+  ///
+  /// ```
+  /// switch (expr) {
+  ///   ...
+  /// }
+  /// ```
+  ///
+  /// This local holds the value of `expr`.
+  ///
+  /// This local is updated with a new value when doing backward jumps.
+  final w.Local switchValueLocal;
+
+  /// Label of the `loop` to use when doing backward jumps
+  final w.Label loopLabel;
+
+  /// When compiling a `default` case, label of the `loop` in the case body, to
+  /// use when doing backward jumps to the same case.
+  w.Label? defaultLoopLabel;
+
+  SwitchBackwardJumpInfo(this.switchValueLocal, this.loopLabel)
+      : defaultLoopLabel = null;
+}
diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart
index 5c7c4ea..4be43ad 100644
--- a/pkg/dart2wasm/lib/target.dart
+++ b/pkg/dart2wasm/lib/target.dart
@@ -47,8 +47,10 @@
         'dart:async',
         'dart:ffi',
         'dart:_internal',
+        'dart:_js_helper',
         'dart:typed_data',
         'dart:nativewrappers',
+        'dart:js_util',
         'dart:js_util_wasm',
         'dart:js_wasm',
         'dart:wasm',
@@ -57,8 +59,10 @@
 
   @override
   List<String> get extraIndexedLibraries => const <String>[
+        'dart:_js_helper',
         'dart:collection',
         'dart:typed_data',
+        'dart:js_util',
         'dart:js_util_wasm',
         'dart:js_wasm',
         'dart:wasm',
@@ -245,7 +249,7 @@
     ClassHierarchy hierarchy, List<Library> interopDependentLibraries) {
   final jsUtilOptimizer = JsUtilWasmOptimizer(coreTypes, hierarchy);
   final staticInteropClassEraser = StaticInteropClassEraser(coreTypes,
-      libraryForJavaScriptObject: 'dart:js_util_wasm',
+      libraryForJavaScriptObject: 'dart:_js_helper',
       classNameOfJavaScriptObject: 'JSValue');
   for (Library library in interopDependentLibraries) {
     jsUtilOptimizer.visitLibrary(library);
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index 8f502da..b86d8f3 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -74,30 +74,28 @@
       return 0;
     }
 
-    var arguments = args.rest;
-    var argumentCount = arguments.length;
-    if (argumentCount > 1) {
-      usageException('Only one file or directory is expected.');
+    var target = _getTarget(args.rest);
+    if (!target.existsSync()) {
+      var entity = target.isDirectory ? 'Directory' : 'File';
+      usageException("$entity doesn't exist: ${target.path}");
     }
 
-    var dir =
-        argumentCount == 0 ? io.Directory.current : io.Directory(arguments[0]);
-    if (!dir.existsSync()) {
-      usageException("Directory doesn't exist: ${dir.path}");
+    if (inTestMode && !target.isDirectory) {
+      usageException('Golden comparison requires a directory argument.');
     }
-    dir = io.Directory(path.canonicalize(path.normalize(dir.absolute.path)));
-    var dirPath = dir.path;
+
+    var fixPath = target.path;
 
     var modeText = dryRun ? ' (dry run)' : '';
 
-    final projectName = path.basename(dirPath);
+    final targetName = path.basename(fixPath);
     Progress? computeFixesProgress = log.progress(
-        'Computing fixes in ${log.ansi.emphasized(projectName)}$modeText');
+        'Computing fixes in ${log.ansi.emphasized(targetName)}$modeText');
 
     var server = AnalysisServer(
       null,
       io.Directory(sdk.sdkPath),
-      [dir],
+      [target],
       commandName: 'fix',
       argResults: argResults,
     );
@@ -123,7 +121,7 @@
       List<SourceFileEdit> edits;
       var pass = 0;
       do {
-        var fixes = await server.requestBulkFixes(dirPath, inTestMode);
+        var fixes = await server.requestBulkFixes(fixPath, inTestMode);
         _mergeDetails(detailsMap, fixes.details);
         edits = fixes.edits;
         _applyEdits(server, edits);
@@ -142,6 +140,7 @@
       computeFixesProgress = null;
     }
 
+    var dir = target.isDirectory ? target as io.Directory : target.parent;
     if (inTestMode) {
       var result = _compareFixesInDirectory(dir);
       log.stdout('Passed: ${result.passCount}, Failed: ${result.failCount}');
@@ -267,6 +266,18 @@
   String _compressWhitespace(String code) =>
       code.replaceAll(RegExp(r'\s+'), ' ');
 
+  io.FileSystemEntity _getTarget(List<String> arguments) {
+    var argumentCount = arguments.length;
+    if (argumentCount == 0) return io.Directory.current.absolute;
+    if (argumentCount > 1) {
+      usageException('Only one file or directory is expected.');
+    }
+    var normalizedPath = path.canonicalize(path.normalize(arguments[0]));
+    return io.FileSystemEntity.isDirectorySync(normalizedPath)
+        ? io.Directory(normalizedPath)
+        : io.File(normalizedPath);
+  }
+
   /// Merge the fixes from the current round's [details] into the [detailsMap].
   void _mergeDetails(Map<String, BulkFix> detailsMap, List<BulkFix> details) {
     for (var detail in details) {
@@ -361,3 +372,7 @@
   /// Initialize a newly created result object.
   _TestResult();
 }
+
+extension on io.FileSystemEntity {
+  bool get isDirectory => this is io.Directory;
+}
diff --git a/pkg/dartdev/lib/src/commands/language_server.dart b/pkg/dartdev/lib/src/commands/language_server.dart
index 65eca06..88bfac3 100644
--- a/pkg/dartdev/lib/src/commands/language_server.dart
+++ b/pkg/dartdev/lib/src/commands/language_server.dart
@@ -8,7 +8,9 @@
 import 'package:args/args.dart';
 
 import '../core.dart';
+import '../sdk.dart';
 import '../utils.dart';
+import '../vm_interop_handler.dart';
 
 class LanguageServerCommand extends DartdevCommand {
   static const String commandName = 'language-server';
@@ -38,11 +40,19 @@
 
   @override
   Future<int> run() async {
-    final driver = server_driver.Driver();
-    driver.start(
-      argResults!.arguments,
-      defaultToLsp: true,
-    );
+    var args = argResults!.arguments;
+    if (!args.any((arg) => arg.startsWith('--protocol'))) {
+      args = [...args, '--protocol=lsp'];
+    }
+
+    if (!Sdk.checkArtifactExists(sdk.analysisServerSnapshot)) return 255;
+
+    VmInteropHandler.run(
+        sdk.analysisServerSnapshot,
+        [
+          ...args,
+        ],
+        packageConfigOverride: null);
 
     // The server will continue to run past the return from this method.
     //
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 2d21669..8f33a56 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -60,89 +60,92 @@
     return await p!.run(['fix', ...args], workingDir: workingDir);
   }
 
-  test('--help', () async {
-    p = project(mainSrc: 'int get foo => 1;\n');
+  group('usage', () {
+    test('--help', () async {
+      p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = await runFix([p!.dirPath, '--help']);
+      var result = await runFix([p!.dirPath, '--help']);
 
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-      result.stdout,
-      contains(
-        'Apply automated fixes to Dart source code.',
-      ),
-    );
-    expect(result.stdout, contains('Usage: dart fix [arguments]'));
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+        result.stdout,
+        contains(
+          'Apply automated fixes to Dart source code.',
+        ),
+      );
+      expect(result.stdout, contains('Usage: dart fix [arguments]'));
+    });
+
+    test('--help --verbose', () async {
+      p = project(mainSrc: 'int get foo => 1;\n');
+
+      var result = await runFix([p!.dirPath, '--help', '--verbose']);
+
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+        result.stdout,
+        contains(
+          'Apply automated fixes to Dart source code.',
+        ),
+      );
+      expect(
+        result.stdout,
+        contains('Usage: dart [vm-options] fix [arguments]'),
+      );
+    });
+
+    test('no args', () async {
+      p = project(mainSrc: 'int get foo => 1;\n');
+
+      var result = await runFix([p!.dirPath]);
+
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout,
+          contains('Apply automated fixes to Dart source code.'));
+    });
   });
 
-  test('--help --verbose', () async {
-    p = project(mainSrc: 'int get foo => 1;\n');
+  group('perform', () {
+    test('--apply (nothing to fix)', () async {
+      p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = await runFix([p!.dirPath, '--help', '--verbose']);
+      var result = await runFix(['--apply', p!.dirPath]);
 
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-      result.stdout,
-      contains(
-        'Apply automated fixes to Dart source code.',
-      ),
-    );
-    expect(
-      result.stdout,
-      contains('Usage: dart [vm-options] fix [arguments]'),
-    );
-  });
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('Nothing to fix!'));
+    });
 
-  test('none', () async {
-    p = project(mainSrc: 'int get foo => 1;\n');
-
-    var result = await runFix([p!.dirPath]);
-
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout, contains('Apply automated fixes to Dart source code.'));
-  });
-
-  test('--apply (none)', () async {
-    p = project(mainSrc: 'int get foo => 1;\n');
-
-    var result = await runFix(['--apply', p!.dirPath]);
-
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('Nothing to fix!'));
-  });
-
-  test('--apply (no args)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply (no args)', () async {
+      p = project(
+        mainSrc: '''
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 linter:
   rules:
     - prefer_single_quotes
 ''',
-    );
+      );
 
-    var result = await runFix(['--apply'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout,
-        stringContainsInOrder([
-          'Applying fixes...',
-          'lib${Platform.pathSeparator}main.dart',
-          '  prefer_single_quotes $bullet 1 fix',
-        ]));
-  });
+      var result = await runFix(['--apply'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            'Applying fixes...',
+            'lib${Platform.pathSeparator}main.dart',
+            '  prefer_single_quotes $bullet 1 fix',
+          ]));
+    });
 
-  test('--dry-run', () async {
-    p = project(
-      mainSrc: '''
+    test('--dry-run', () async {
+      p = project(
+        mainSrc: '''
 class A {
   String a() => "";
 }
@@ -151,82 +154,107 @@
   String a() => "";
 }
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 linter:
   rules:
     - annotate_overrides
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--dry-run', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout,
-        stringContainsInOrder([
-          '3 proposed fixes in 1 file.',
-          'lib${Platform.pathSeparator}main.dart',
-          '  annotate_overrides $bullet 1 fix',
-          '  prefer_single_quotes $bullet 2 fixes',
-        ]));
-  });
+      );
+      var result = await runFix(['--dry-run', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            '3 proposed fixes in 1 file.',
+            'lib${Platform.pathSeparator}main.dart',
+            '  annotate_overrides $bullet 1 fix',
+            '  prefer_single_quotes $bullet 2 fixes',
+          ]));
+    });
 
-  test('--apply (.)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply lib/main.dart', () async {
+      p = project(
+        mainSrc: '''
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 linter:
   rules:
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout,
-        stringContainsInOrder([
-          'Applying fixes...',
-          'lib${Platform.pathSeparator}main.dart',
-          '  prefer_single_quotes $bullet 1 fix',
-          '1 fix made in 1 file.',
-        ]));
-  });
+      );
+      var result = await runFix(['--apply', path.join('lib', 'main.dart')],
+          workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            'Applying fixes...',
+            'main.dart',
+            '  prefer_single_quotes $bullet 1 fix',
+            '1 fix made in 1 file.',
+          ]));
+    });
 
-  test('--apply (contradictory lints do not loop infinitely)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply (.)', () async {
+      p = project(
+        mainSrc: '''
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
+linter:
+  rules:
+    - prefer_single_quotes
+''',
+      );
+      var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            'Applying fixes...',
+            'lib${Platform.pathSeparator}main.dart',
+            '  prefer_single_quotes $bullet 1 fix',
+            '1 fix made in 1 file.',
+          ]));
+    });
+
+    test('--apply (contradictory lints do not loop infinitely)', () async {
+      p = project(
+        mainSrc: '''
+var x = "";
+''',
+        analysisOptions: '''
 linter:
   rules:
     - prefer_double_quotes
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout,
-        stringContainsInOrder([
-          'Applying fixes...',
-          'lib${Platform.pathSeparator}main.dart',
-          '  prefer_double_quotes $bullet 2 fixes',
-          '  prefer_single_quotes $bullet 2 fixes',
-          '4 fixes made in 1 file.',
-        ]));
-  });
+      );
+      var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            'Applying fixes...',
+            'lib${Platform.pathSeparator}main.dart',
+            '  prefer_double_quotes $bullet 2 fixes',
+            '  prefer_single_quotes $bullet 2 fixes',
+            '4 fixes made in 1 file.',
+          ]));
+    });
 
-  test('--apply (excludes)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply (excludes)', () async {
+      p = project(
+        mainSrc: '''
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 analyzer:
   exclude:
     - lib/**
@@ -234,59 +262,95 @@
   rules:
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('Nothing to fix!'));
-  });
+      );
+      var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('Nothing to fix!'));
+    });
 
-  test('--apply (ignores)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply (ignores)', () async {
+      p = project(
+        mainSrc: '''
 // ignore: prefer_single_quotes
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 linter:
   rules:
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('Nothing to fix!'));
-  });
+      );
+      var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('Nothing to fix!'));
+    });
 
-  test('--apply (unused imports require a second pass)', () async {
-    p = project(
-      mainSrc: '''
+    test('--apply (unused imports require a second pass)', () async {
+      p = project(
+        mainSrc: '''
 import 'dart:math';
 
 var x = "";
 ''',
-      analysisOptions: '''
+        analysisOptions: '''
 linter:
   rules:
     - prefer_single_quotes
 ''',
-    );
-    var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(
-        result.stdout,
-        stringContainsInOrder([
-          'Applying fixes...',
-          'lib${Platform.pathSeparator}main.dart',
-          '  prefer_single_quotes $bullet 1 fix',
-          '  unused_import $bullet 1 fix',
-          '2 fixes made in 1 file.',
-        ]));
+      );
+      var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(
+          result.stdout,
+          stringContainsInOrder([
+            'Applying fixes...',
+            'lib${Platform.pathSeparator}main.dart',
+            '  prefer_single_quotes $bullet 1 fix',
+            '  unused_import $bullet 1 fix',
+            '2 fixes made in 1 file.',
+          ]));
+    });
   });
 
   group('compare-to-golden', () {
+    test('target is not a directory', () async {
+      p = project(
+        mainSrc: '''
+class A {
+  String a() => "";
+}
+
+class B extends A {
+  String a() => "";
+}
+''',
+        analysisOptions: '''
+linter:
+  rules:
+    - annotate_overrides
+    - prefer_single_quotes
+''',
+      );
+      p!.file('lib/main.dart.expect', '''
+class A {
+  String a() => '';
+}
+
+class B extends A {
+  @override
+  String a() => '';
+}
+''');
+      result = await runFix(['--compare-to-golden', 'lib/main.dart.expect'],
+          workingDir: p!.dirPath);
+      expect(result.exitCode, 64);
+      expect(result.stderr,
+          startsWith('Golden comparison requires a directory argument.'));
+    });
+
     test('applied fixes do not match expected', () async {
       p = project(
         mainSrc: '''
diff --git a/pkg/dds/test/devtools_observatory_connection_test.dart b/pkg/dds/test/devtools_observatory_connection_test.dart
index ae3eb38..fd56b33 100644
--- a/pkg/dds/test/devtools_observatory_connection_test.dart
+++ b/pkg/dds/test/devtools_observatory_connection_test.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart=2.10
-
 import 'dart:convert';
 import 'dart:io';
 
@@ -15,8 +13,8 @@
 // Regression test for https://github.com/dart-lang/sdk/issues/45933.
 
 void main() {
-  Process process;
-  DartDevelopmentService dds;
+  Process? process;
+  DartDevelopmentService? dds;
 
   setUp(() async {
     // We don't care what's actually running in the target process for this
@@ -35,7 +33,7 @@
     process = null;
   });
 
-  defineTest({bool authCodesEnabled}) {
+  defineTest({required bool authCodesEnabled}) {
     test(
         'Ensure Observatory and DevTools assets are available with '
         '${authCodesEnabled ? '' : 'no'} auth codes', () async {
@@ -46,12 +44,12 @@
           customBuildDirectoryPath: devtoolsAppUri(prefix: '../../../'),
         ),
       );
-      expect(dds.isRunning, true);
+      expect(dds!.isRunning, true);
 
       final client = HttpClient();
 
       // Check that Observatory assets are accessible.
-      final observatoryRequest = await client.getUrl(dds.uri);
+      final observatoryRequest = await client.getUrl(dds!.uri!);
       final observatoryResponse = await observatoryRequest.close();
       expect(observatoryResponse.statusCode, 200);
       final observatoryContent =
@@ -59,7 +57,7 @@
       expect(observatoryContent, startsWith('<!DOCTYPE html>'));
 
       // Check that DevTools assets are accessible.
-      final devtoolsRequest = await client.getUrl(dds.devToolsUri);
+      final devtoolsRequest = await client.getUrl(dds!.devToolsUri!);
       final devtoolsResponse = await devtoolsRequest.close();
       expect(devtoolsResponse.statusCode, 200);
       final devtoolsContent =
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 9e23df4..b694dff 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -125,9 +125,9 @@
 InitializedCompilerState initializeCompiler(
     InitializedCompilerState? oldState,
     Target target,
-    Uri librariesSpecificationUri,
+    Uri? librariesSpecificationUri,
     List<Uri> additionalDills,
-    Uri packagesFileUri,
+    Uri? packagesFileUri,
     {required Map<ExperimentalFlag, bool> explicitExperimentalFlags,
     Map<String, String>? environmentDefines,
     bool verify: false,
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 75dff4b..60370ac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -6363,8 +6363,8 @@
         }
       }
     }
-    bool isExhaustive =
-        hasDefault || (enumFields != null && enumFields.isEmpty);
+    node.isExplicitlyExhaustive = enumFields != null && enumFields.isEmpty;
+    bool isExhaustive = node.isExplicitlyExhaustive || hasDefault;
     inferrer.flowAnalysis.switchStatement_end(isExhaustive);
     Statement? replacement;
     if (isExhaustive &&
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 815a290..ca5b58f 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -2973,6 +2973,7 @@
 suspect
 swap
 switch
+switches
 symbol
 symbols
 symmetric
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect
index 4b80ddd..a625cee 100644
--- a/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect
@@ -5,39 +5,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → self::C
     return new self::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{self::C::_#C#a} = value;
+    this.{self::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{self::C::_#C#b}{core::int}, "b");
-    this.{self::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{self::C::_#C#b#F}{core::int}, "b");
+    this.{self::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{self::C::_#C#c}{core::int};
+    core::int value = this.{self::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{self::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{self::C::_#C#c} = value;
+    this.{self::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{self::C::_#C#d}{core::int};
+    core::int value = this.{self::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{self::C::_#C#d}{core::int}, "d");
-      value = this.{self::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{self::C::_#C#d#FI}{core::int}, "d");
+      value = this.{self::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect
index 4b80ddd..a625cee 100644
--- a/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect
@@ -5,39 +5,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → self::C
     return new self::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{self::C::_#C#a} = value;
+    this.{self::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{self::C::_#C#b}{core::int}, "b");
-    this.{self::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{self::C::_#C#b#F}{core::int}, "b");
+    this.{self::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{self::C::_#C#c}{core::int};
+    core::int value = this.{self::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{self::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{self::C::_#C#c} = value;
+    this.{self::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{self::C::_#C#d}{core::int};
+    core::int value = this.{self::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{self::C::_#C#d}{core::int}, "d");
-      value = this.{self::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{self::C::_#C#d#FI}{core::int}, "d");
+      value = this.{self::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect
index b0d37be..a4aaaff 100644
--- a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect
@@ -92,39 +92,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → mai::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → mai::C
     return new mai::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{mai::C::_#C#a} = value;
+    this.{mai::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
-    this.{mai::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b#F}{core::int}, "b");
+    this.{mai::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{mai::C::_#C#c}{core::int};
+    core::int value = this.{mai::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{mai::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{mai::C::_#C#c} = value;
+    this.{mai::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{mai::C::_#C#d}{core::int};
+    core::int value = this.{mai::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
-      value = this.{mai::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d#FI}{core::int}, "d");
+      value = this.{mai::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect
index e24d5f5..417686a 100644
--- a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect
@@ -92,39 +92,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → mai::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → mai::C
     return new mai::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{mai::C::_#C#a} = value;
+    this.{mai::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
-    this.{mai::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b#F}{core::int}, "b");
+    this.{mai::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{mai::C::_#C#c}{core::int};
+    core::int value = this.{mai::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{mai::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{mai::C::_#C#c} = value;
+    this.{mai::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{mai::C::_#C#d}{core::int};
+    core::int value = this.{mai::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
-      value = this.{mai::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d#FI}{core::int}, "d");
+      value = this.{mai::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect
index b0d37be..a4aaaff 100644
--- a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect
@@ -92,39 +92,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → mai::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → mai::C
     return new mai::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{mai::C::_#C#a} = value;
+    this.{mai::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
-    this.{mai::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b#F}{core::int}, "b");
+    this.{mai::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{mai::C::_#C#c}{core::int};
+    core::int value = this.{mai::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{mai::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{mai::C::_#C#c} = value;
+    this.{mai::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{mai::C::_#C#d}{core::int};
+    core::int value = this.{mai::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
-      value = this.{mai::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d#FI}{core::int}, "d");
+      value = this.{mai::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect
index 7917e7d..cf88a25 100644
--- a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect
@@ -40,33 +40,33 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#A = _in::createSentinel<core::int>();
+  field core::int _#C#d#F = _in::createSentinel<core::int>();
   synthetic constructor •() → mai::C
     ;
   static method _#new#tearOff() → mai::C
     return new mai::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{mai::C::_#C#a} = value;
+    this.{mai::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
-    this.{mai::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b#F}{core::int}, "b");
+    this.{mai::C::_#C#b#F} = value;
   }
   get c() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#c}{core::int}, "c");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#c#A}{core::int}, "c");
   set c(core::int value) → void
-    this.{mai::C::_#C#c} = value;
+    this.{mai::C::_#C#c#A} = value;
   get d() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#d}{core::int}, "d");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#d#F}{core::int}, "d");
   set d(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
-    this.{mai::C::_#C#d} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#d#F}{core::int}, "d");
+    this.{mai::C::_#C#d#F} = value;
   }
 }
 class Statics extends core::Object {
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect
index e24d5f5..417686a 100644
--- a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect
@@ -92,39 +92,39 @@
 import "dart:_internal" as _in;
 
 class C extends core::Object {
-  field core::int _#C#a = _in::createSentinel<core::int>();
-  field core::int _#C#b = _in::createSentinel<core::int>();
-  field core::int _#C#c = _in::createSentinel<core::int>();
-  field core::int _#C#d = _in::createSentinel<core::int>();
+  field core::int _#C#a#A = _in::createSentinel<core::int>();
+  field core::int _#C#b#F = _in::createSentinel<core::int>();
+  field core::int _#C#c#AI = _in::createSentinel<core::int>();
+  field core::int _#C#d#FI = _in::createSentinel<core::int>();
   synthetic constructor •() → mai::C
     : super core::Object::•()
     ;
   static method _#new#tearOff() → mai::C
     return new mai::C::•();
   get a() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a#A}{core::int}, "a");
   set a(core::int value) → void
-    this.{mai::C::_#C#a} = value;
+    this.{mai::C::_#C#a#A} = value;
   get b() → core::int
-    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+    return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b#F}{core::int}, "b");
   set b(core::int value) → void {
-    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
-    this.{mai::C::_#C#b} = value;
+    _la::_lateWriteOnceCheck(this.{mai::C::_#C#b#F}{core::int}, "b");
+    this.{mai::C::_#C#b#F} = value;
   }
   get c() → core::int {
-    core::int value = this.{mai::C::_#C#c}{core::int};
+    core::int value = this.{mai::C::_#C#c#AI}{core::int};
     if(_in::isSentinel(value))
-      value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+      value = this.{mai::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
     return value;
   }
   set c(core::int value) → void
-    this.{mai::C::_#C#c} = value;
+    this.{mai::C::_#C#c#AI} = value;
   get d() → core::int {
-    core::int value = this.{mai::C::_#C#d}{core::int};
+    core::int value = this.{mai::C::_#C#d#FI}{core::int};
     if(_in::isSentinel(value)) {
       final core::int result = 1.{core::int::unary-}(){() → core::int};
-      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
-      value = this.{mai::C::_#C#d} = result;
+      _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d#FI}{core::int}, "d");
+      value = this.{mai::C::_#C#d#FI} = result;
     }
     return value;
   }
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
index 9921c30..2e558b3 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
@@ -107,7 +107,7 @@
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -176,7 +176,7 @@
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
-    switch(e) {
+    switch(e) /*isExplicitlyExhaustive*/ {
       #L5:
       case #C3:
         {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index cc1f3a8..1415bf4 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -118,7 +118,7 @@
 }
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -198,7 +198,7 @@
   }
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
-    switch(e) {
+    switch(e) /*isExplicitlyExhaustive*/ {
       #L5:
       case #C3:
         {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
index e388444..affb3d2 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
@@ -108,7 +108,7 @@
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -180,7 +180,7 @@
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
-    switch(e) {
+    switch(e) /*isExplicitlyExhaustive*/ {
       #L6:
       case #C3:
         {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
index e388444..affb3d2 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
@@ -108,7 +108,7 @@
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -180,7 +180,7 @@
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
-    switch(e) {
+    switch(e) /*isExplicitlyExhaustive*/ {
       #L6:
       case #C3:
         {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index 8108220..c823636 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -119,7 +119,7 @@
 }
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -202,7 +202,7 @@
   }
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
-    switch(e) {
+    switch(e) /*isExplicitlyExhaustive*/ {
       #L6:
       case #C3:
         {
diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.expect
index d8b9a5d..d4f91be 100644
--- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.expect
@@ -33,7 +33,7 @@
     ^" in null;
 }
 static method method2(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L2:
     case #C3:
     case #C6:
@@ -63,7 +63,7 @@
   }
 }
 static method method4(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L6:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.transformed.expect
index d8b9a5d..d4f91be 100644
--- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
     ^" in null;
 }
 static method method2(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L2:
     case #C3:
     case #C6:
@@ -63,7 +63,7 @@
   }
 }
 static method method4(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L6:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect
index 4853ed6..6a960bc 100644
--- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect
@@ -34,7 +34,7 @@
     ^" in null;
 }
 static method method2(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L2:
     case #C3:
     case #C6:
@@ -67,7 +67,7 @@
   }
 }
 static method method4(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L7:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.modular.expect
index 4853ed6..6a960bc 100644
--- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.modular.expect
@@ -34,7 +34,7 @@
     ^" in null;
 }
 static method method2(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L2:
     case #C3:
     case #C6:
@@ -67,7 +67,7 @@
   }
 }
 static method method4(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L7:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect
index 4853ed6..6a960bc 100644
--- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect
@@ -34,7 +34,7 @@
     ^" in null;
 }
 static method method2(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L2:
     case #C3:
     case #C6:
@@ -67,7 +67,7 @@
   }
 }
 static method method4(self::Enum? e) → core::int {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L7:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
index ed2219b..0524cac 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
@@ -170,8 +170,8 @@
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> SymbolConstant(#noFolding)
 Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> SymbolConstant(#clear)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> SymbolConstant(#clear)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 268, effectively constant: 91
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
index c6672f7..4cd4db8 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
@@ -523,7 +523,7 @@
   let final Never #t75 = f(){() → Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
 }
 static method switchOnEnum(uns::E e) → dynamic {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -541,7 +541,7 @@
 }
 static method switchOnEnumWithBreak(uns::E e) → dynamic {
   #L4:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L5:
     case #C3:
       {
@@ -559,7 +559,7 @@
 }
 static method switchOnEnumWithFallThrough1(uns::E e) → dynamic {
   #L8:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L9:
     case #C3:
       {
@@ -577,7 +577,7 @@
 }
 static method switchOnEnumWithFallThrough2(uns::E e) → dynamic {
   #L12:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L13:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.modular.expect
index c6672f7..4cd4db8 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.modular.expect
@@ -523,7 +523,7 @@
   let final Never #t75 = f(){() → Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
 }
 static method switchOnEnum(uns::E e) → dynamic {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -541,7 +541,7 @@
 }
 static method switchOnEnumWithBreak(uns::E e) → dynamic {
   #L4:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L5:
     case #C3:
       {
@@ -559,7 +559,7 @@
 }
 static method switchOnEnumWithFallThrough1(uns::E e) → dynamic {
   #L8:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L9:
     case #C3:
       {
@@ -577,7 +577,7 @@
 }
 static method switchOnEnumWithFallThrough2(uns::E e) → dynamic {
   #L12:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L13:
     case #C3:
     case #C6:
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
index 0540b4d..f502ea8 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
@@ -523,7 +523,7 @@
   let final Never #t75 = f(){() → Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
 }
 static method switchOnEnum(uns::E e) → dynamic {
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L1:
     case #C3:
       {
@@ -541,7 +541,7 @@
 }
 static method switchOnEnumWithBreak(uns::E e) → dynamic {
   #L4:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L5:
     case #C3:
       {
@@ -559,7 +559,7 @@
 }
 static method switchOnEnumWithFallThrough1(uns::E e) → dynamic {
   #L8:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L9:
     case #C3:
       {
@@ -577,7 +577,7 @@
 }
 static method switchOnEnumWithFallThrough2(uns::E e) → dynamic {
   #L12:
-  switch(e) {
+  switch(e) /*isExplicitlyExhaustive*/ {
     #L13:
     case #C3:
     case #C6:
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 8bd5bbb..b2489b6 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -58,7 +58,7 @@
           'supported when --aot and --minimal-kernel are not used.',
       defaultsTo: null)
   ..addFlag('compact-async',
-      help: 'Enable new compact async/await implementation.', defaultsTo: true)
+      help: 'Enable new compact async/await implementation.', defaultsTo: null)
   ..addFlag('tfa',
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
@@ -541,7 +541,7 @@
       nullSafety: compilerOptions.nnbdMode == NnbdMode.Strong,
       supportMirrors: options['support-mirrors'] ??
           !(options['aot'] || options['minimal-kernel']),
-      compactAsync: options['compact-async'],
+      compactAsync: options['compact-async'] ?? options['aot'],
     );
     if (compilerOptions.target == null) {
       print('Failed to create front-end target ${options['target']}.');
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 25388c5..8d76bd1 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 81;
+  UInt32 formatVersion = 82;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -1331,6 +1331,7 @@
 type SwitchStatement extends Statement {
   Byte tag = 71;
   FileOffset fileOffset;
+  Byte isExplicitlyExhaustive; // 1 if exhaustive, 0 if not.
   Expression expression;
   List<SwitchCase> cases;
 }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 5f049a0..2cd92cc 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -9891,11 +9891,26 @@
   Expression expression;
   final List<SwitchCase> cases;
 
-  SwitchStatement(this.expression, this.cases) {
+  /// For enum switches, whether all enum values are covered by a switch case.
+  /// Initialized during type inference.
+  bool isExplicitlyExhaustive;
+
+  SwitchStatement(this.expression, this.cases,
+      {this.isExplicitlyExhaustive = false}) {
     expression.parent = this;
     setParents(cases, this);
   }
 
+  /// Whether the switch has a `default` case.
+  bool get hasDefault {
+    assert(cases.every((c) => c == cases.last || !c.isDefault));
+    return cases.isNotEmpty && cases.last.isDefault;
+  }
+
+  /// Whether the switch is guaranteed to hit one of the cases (including the
+  /// default case, if present).
+  bool get isExhaustive => isExplicitlyExhaustive || hasDefault;
+
   @override
   R accept<R>(StatementVisitor<R> v) => v.visitSwitchStatement(this);
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index d2a39f1..e8e75f4 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2836,6 +2836,7 @@
 
   Statement _readSwitchStatement() {
     int offset = readOffset();
+    bool isExplicitlyExhaustive = readByte() == 1;
     Expression expression = readExpression();
     int count = readUInt30();
     List<SwitchCase> cases;
@@ -2855,7 +2856,9 @@
       _readSwitchCaseInto(cases[i]);
     }
     switchCaseStack.length -= count;
-    return new SwitchStatement(expression, cases)..fileOffset = offset;
+    return new SwitchStatement(expression, cases,
+        isExplicitlyExhaustive: isExplicitlyExhaustive)
+      ..fileOffset = offset;
   }
 
   Statement _readContinueSwitchStatement() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index dab017c..7c9ac33 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2190,6 +2190,7 @@
     switchCaseIndexer.enter(node);
     writeByte(Tag.SwitchStatement);
     writeOffset(node.fileOffset);
+    writeByte(node.isExplicitlyExhaustive ? 1 : 0);
     writeNode(node.expression);
     writeSwitchCaseNodeList(node.cases);
     switchCaseIndexer.exit(node);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index b0a13a0..754bbd6 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -179,7 +179,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 = 81;
+  static const int BinaryFormatVersion = 82;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 348ff65..22e011b 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -492,7 +492,8 @@
           isDefault: switchCase.isDefault);
     }
     return new SwitchStatement(
-        clone(node.expression), node.cases.map(clone).toList());
+        clone(node.expression), node.cases.map(clone).toList(),
+        isExplicitlyExhaustive: node.isExplicitlyExhaustive);
   }
 
   @override
diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart
index 015d021..a5efbee 100644
--- a/pkg/kernel/lib/src/equivalence.dart
+++ b/pkg/kernel/lib/src/equivalence.dart
@@ -3707,6 +3707,9 @@
     if (!checkSwitchStatement_cases(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkSwitchStatement_isExplicitlyExhaustive(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkSwitchStatement_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -6881,6 +6884,12 @@
         node.cases, other.cases, visitor.checkNodes, 'cases');
   }
 
+  bool checkSwitchStatement_isExplicitlyExhaustive(
+      EquivalenceVisitor visitor, SwitchStatement node, SwitchStatement other) {
+    return visitor.checkValues(node.isExplicitlyExhaustive,
+        other.isExplicitlyExhaustive, 'isExplicitlyExhaustive');
+  }
+
   bool checkSwitchStatement_fileOffset(
       EquivalenceVisitor visitor, SwitchStatement node, SwitchStatement other) {
     return checkStatement_fileOffset(visitor, node, other);
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 707efa0..3525eab 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -22,7 +22,7 @@
       {this.trackWidgetCreation = false,
       this.enableNullSafety = false,
       this.supportMirrors = true,
-      this.compactAsync = true});
+      this.compactAsync = false});
 
   @override
   bool operator ==(other) {
@@ -786,7 +786,8 @@
       this.unsupportedDartLibraries: const {}})
       : super(
             trackWidgetCreation: trackWidgetCreation,
-            enableNullSafety: enableNullSafety);
+            enableNullSafety: enableNullSafety,
+            compactAsync: true);
 }
 
 mixin TestTargetMixin on Target {
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 722da3d..d7946d2 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -2295,7 +2295,11 @@
     writeWord('switch');
     writeSymbol('(');
     writeExpression(node.expression);
-    endLine(') {');
+    writeSymbol(')');
+    if (node.isExplicitlyExhaustive) {
+      writeWord(" /*isExplicitlyExhaustive*/");
+    }
+    endLine(' {');
     ++indentation;
     node.cases.forEach(writeNode);
     --indentation;
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index ed266eb..0f2f6ac 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -1226,7 +1226,8 @@
         var enclosingElement = element.enclosingElement;
         if (enclosingElement is ConstructorElement &&
             enclosingElement.isFactory &&
-            enclosingElement.redirectedConstructor != null) {
+            enclosingElement.redirectedConstructor != null &&
+            !node.declaredElement!.hasRequired) {
           // Redirecting factory constructors inherit their parameters' default
           // values from the constructors they redirect to, so the lack of a
           // default value doesn't mean the parameter has to be nullable.
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index c920737..d26b884 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -805,6 +805,42 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_at_required_to_required_in_redirecting_factory() async {
+    // Redirecting factory constructors have special logic to suppress some of
+    // the usual heuristics for adding `required`, since it's allowed for a
+    // redirecting factory constructor to have a non-required non-nullable
+    // argument with no default.  But we need to make sure that we still convert
+    // `@required` to `required`.
+    addMetaPackage();
+    var content = r'''
+import 'package:meta/meta.dart';
+abstract class A {
+  int get v;
+  A._();
+  factory A({@required int v}) = B._;
+}
+class B extends A {
+  @override
+  final int v;
+  B._({this.v}) : super._();
+}
+''';
+    var expected = r'''
+import 'package:meta/meta.dart';
+abstract class A {
+  int? get v;
+  A._();
+  factory A({required int v}) = B._;
+}
+class B extends A {
+  @override
+  final int? v;
+  B._({this.v}) : super._();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_avoid_redundant_future_or() async {
     // FutureOr<int?> and FutureOr<int?>? are equivalent types; we never insert
     // the redundant second `?`.
diff --git a/pkg/scrape/lib/src/scrape_visitor.dart b/pkg/scrape/lib/src/scrape_visitor.dart
index 38ca2c5..7869df9 100644
--- a/pkg/scrape/lib/src/scrape_visitor.dart
+++ b/pkg/scrape/lib/src/scrape_visitor.dart
@@ -38,7 +38,7 @@
 
   // TODO(rnystrom): Remove this in favor of using surveyor for these kinds of
   // analyses.
-  /// Whether the visitor is currently inside a Flutter "build" method,
+  /// Whether the visitor is currently inside Flutter's "build" method,
   /// either directly or nested inside some other function inside one.
   ///
   /// This is only an approximate guess. It assumes a method is a "build"-like
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index 397ebad..41df706 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -22,7 +22,7 @@
 
   /// Gets the source whose lowercase name is [name] or `null` if no source
   /// with that name could be found.
-  static ErrorSource find(String name) {
+  static ErrorSource find(String /*!*/ name) {
     for (var source in all) {
       if (source.marker == name) return source;
     }
@@ -121,8 +121,9 @@
   ///
   /// Also describes any mismatches between the context messages in the expected
   /// and actual errors.
-  static String validateExpectations(Iterable<StaticError> expectedErrors,
-      Iterable<StaticError> actualErrors) {
+  static String validateExpectations(
+      Iterable<StaticError /*!*/ > expectedErrors,
+      Iterable<StaticError /*!*/ > actualErrors) {
     var expected = expectedErrors.toList();
     var actual = actualErrors.toList();
 
@@ -242,13 +243,14 @@
 
   /// The number of characters in the error location.
   ///
-  /// This is optional. The CFE only reports error location, but not length.
-  final int length;
+  /// `0` means no length was reported. The CFE only reports error location,
+  /// but not length.
+  final int /*!*/ length;
 
   /// The front end this error is for.
   final ErrorSource source;
 
-  final String message;
+  final String /*!*/ message;
 
   /// Additional context messages associated with this error.
   final List<StaticError> contextMessages = [];
@@ -271,17 +273,18 @@
   /// error is tested, a front end is expected to report *some* error on that
   /// error's line, but it can be any location, error code, or message.
   StaticError(this.source, this.message,
-      {this.line, this.column, this.length, Set<int> sourceLines})
+      {this.line, this.column, this.length = 0, Set<int> sourceLines})
       : sourceLines = {...?sourceLines} {
     // Must have a location.
     assert(line != null);
     assert(column != null);
+    assert(length != null);
   }
 
   /// A textual description of this error's location.
   String get location {
     var result = "line $line, column $column";
-    if (length != null) result += ", length $length";
+    if (length > 0) result += ", length $length";
     return result;
   }
 
@@ -317,7 +320,7 @@
   String toString() {
     var buffer = StringBuffer("StaticError(");
     buffer.write("line: $line, column: $column");
-    if (length != null) buffer.write(", length: $length");
+    if (length > 0) buffer.write(", length: $length");
     buffer.write(", message: '$message'");
 
     if (contextMessages.isNotEmpty) {
@@ -337,8 +340,8 @@
     if (column != other.column) return column.compareTo(other.column);
 
     // Sort no length after all other lengths.
-    if (length == null && other.length != null) return 1;
-    if (length != null && other.length == null) return -1;
+    if (length == 0 && other.length > 0) return 1;
+    if (length > 0 && other.length == 0) return -1;
     if (length != other.length) return length.compareTo(other.length);
 
     if (source != other.source) {
@@ -368,7 +371,7 @@
   int get hashCode =>
       3 * line.hashCode +
       5 * column.hashCode +
-      7 * (length ?? 0).hashCode +
+      7 * length.hashCode +
       11 * source.hashCode +
       13 * message.hashCode;
 
@@ -388,7 +391,7 @@
     // Ignore column and length for unspecified errors.
     if (isSpecified) {
       if (column != actual.column) return false;
-      if (actual.length != null && length != actual.length) return false;
+      if (actual.length > 0 && length != actual.length) return false;
     }
 
     return true;
@@ -412,7 +415,7 @@
         actualMismatches.add("column ${actual.column}");
       }
 
-      if (actual.length != null && length != actual.length) {
+      if (actual.length > 0 && length != actual.length) {
         expectedMismatches.add("length $length");
         actualMismatches.add("length ${actual.length}");
       }
@@ -561,7 +564,8 @@
   }
 
   /// Finishes parsing a series of error expectations after parsing a location.
-  void _parseErrors({int line, int column, int length}) {
+  void _parseErrors(
+      {/*required*/ int line, /*required*/ int column, int length = 0}) {
     var locationLine = _currentLine;
     var parsedError = false;
 
@@ -573,13 +577,13 @@
       var number = match[2] != null ? int.parse(match[2]) : null;
 
       var sourceName = match[1];
-      var source = ErrorSource.find(sourceName);
-      if (source == null) _fail("Unknown front end '[$sourceName]'.");
+      var source = ErrorSource.find(sourceName) ??
+          _fail("Unknown front end '[$sourceName]'.");
       if (source == ErrorSource.context && number == null) {
         _fail("Context messages must have an error number.");
       }
 
-      var message = match[3];
+      var message = match[3] /*!*/;
       _advance();
       var sourceLines = {locationLine, _currentLine};
 
@@ -616,7 +620,7 @@
       // TODO(rnystrom): Stop doing this when the CFE reports error lengths.
       var errorLength = length;
       if (errorLength == 1 && source == ErrorSource.cfe) {
-        errorLength = null;
+        errorLength = 0;
       }
 
       var error = StaticError(source, message,
@@ -703,7 +707,9 @@
     return line;
   }
 
-  void _fail(String message) {
+  // TODO(athom): remove when migrated to null safety.
+  // ignore: sdk_version_never
+  Never _fail(String message) {
     throw FormatException("Test error on line ${_currentLine + 1}: $message");
   }
 }
diff --git a/pkg/test_runner/test/static_error_test.dart b/pkg/test_runner/test/static_error_test.dart
index e716fd5..7442db8 100644
--- a/pkg/test_runner/test/static_error_test.dart
+++ b/pkg/test_runner/test/static_error_test.dart
@@ -31,7 +31,7 @@
   Expect.equals(cfe.message, "Error.");
   Expect.equals(cfe.line, 4);
   Expect.equals(cfe.column, 5);
-  Expect.isNull(cfe.length);
+  Expect.equals(cfe.length, 0);
   Expect.isTrue(cfe.isSpecified);
   Expect.isTrue(cfe.sourceLines.isEmpty);
 
@@ -223,6 +223,69 @@
     makeError(line: 1, column: 3, length: 3, webError: "Web 3."),
   ], null);
 
+  // Same message.
+  expectValidate([
+    makeError(line: 1, column: 2, length: 1, cfeError: "message"),
+    makeError(line: 2, column: 3, length: 2, cfeError: "message"),
+  ], [
+    makeError(line: 1, column: 2, length: 1, cfeError: "message"),
+    makeError(line: 2, column: 3, length: 2, cfeError: "message"),
+    makeError(line: 3, column: 3, length: 3, cfeError: "message"),
+  ], '- Unexpected error at line 3, column 3, length 3: message');
+
+  // Same location.
+  expectValidate([
+    makeError(line: 1, column: 2, length: 1, cfeError: "message 1"),
+    makeError(line: 1, column: 2, length: 1, cfeError: "message 2"),
+  ], [
+    makeError(line: 1, column: 2, length: 1, cfeError: "wrong 1"),
+    makeError(line: 1, column: 2, length: 1, cfeError: "wrong 2"),
+    makeError(line: 1, column: 2, length: 1, cfeError: "wrong 3"),
+  ], '''
+- Wrong message at line 1, column 2, length 1: wrong 1
+  Expected: message 1
+
+- Wrong message at line 1, column 2, length 1: wrong 2
+  Expected: message 2
+
+- Unexpected error at line 1, column 2, length 1: wrong 3''');
+
+  // Prefer match over wrong message.
+  expectValidate([
+    makeError(line: 10, column: 1, length: 1, cfeError: "match"),
+    makeError(line: 10, column: 1, length: 1, cfeError: "a wrong message"),
+  ], [
+    makeError(line: 1, column: 1, length: 1, cfeError: /* not a */ "match"),
+    makeError(line: 10, column: 1, length: 1, cfeError: "match"),
+  ], '''
+- Missing expected error at line 10, column 1, length 1: a wrong message
+
+- Unexpected error at line 1, column 1, length 1: match''');
+
+  // Combined.
+  expectValidate([
+    makeError(line: 10, column: 1, length: 1, cfeError: "match"),
+    makeError(line: 20, column: 2, length: 2, cfeError: "missing"),
+    makeError(line: 20, column: 2, length: 2, cfeError: "message"),
+    makeError(line: 30, column: 3, length: 3, cfeError: "wrong location"),
+    makeError(line: 40, column: 4, length: 4, cfeError: "match"),
+  ], [
+    makeError(line: 1, column: 2, length: 1, cfeError: "unexpected"),
+    makeError(line: 10, column: 3, length: 3, cfeError: "wrong location"),
+    makeError(line: 20, column: 2, length: 2, cfeError: "wrong message"),
+    makeError(line: 10, column: 1, length: 1, cfeError: "match"),
+    makeError(line: 40, column: 4, length: 4, cfeError: "match"),
+  ], '''
+- Wrong error location line 30, column 3, length 3: wrong location
+  Expected line 30 but was line 10.
+
+- Wrong message at line 20, column 2, length 2: wrong message
+  Expected: message
+
+- Missing expected error at line 20, column 2, length 2: missing
+
+- Unexpected error at line 1, column 2, length 1: unexpected''');
+
   // If expectation has context, actual must match it.
   expectValidate([
     makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
diff --git a/pkg/test_runner/test/test_file_test.dart b/pkg/test_runner/test/test_file_test.dart
index 8e5ddc1..9b1f445 100644
--- a/pkg/test_runner/test/test_file_test.dart
+++ b/pkg/test_runner/test/test_file_test.dart
@@ -549,10 +549,10 @@
 /\/ [cfe] Message.
 /\/ [web] Web message.
 """, [
-    makeError(line: 1, column: 9, length: null, cfeError: "Message."),
+    makeError(line: 1, column: 9, length: 0, cfeError: "Message."),
     makeError(line: 5, column: 9, length: 1, analyzerError: "Error.BAD"),
-    makeError(line: 5, column: 9, length: null, cfeError: "Message."),
-    makeError(line: 10, column: 9, length: null, cfeError: "Message."),
+    makeError(line: 5, column: 9, length: 0, cfeError: "Message."),
+    makeError(line: 10, column: 9, length: 0, cfeError: "Message."),
     makeError(line: 10, column: 9, length: 1, webError: "Web message."),
   ]);
 }
diff --git a/pkg/test_runner/test/utils.dart b/pkg/test_runner/test/utils.dart
index e0d8f07..f5e14cb 100644
--- a/pkg/test_runner/test/utils.dart
+++ b/pkg/test_runner/test/utils.dart
@@ -33,7 +33,7 @@
 StaticError makeError(
     {int line = 1,
     int column = 2,
-    int length,
+    int length = 0,
     String analyzerError,
     String cfeError,
     String webError,
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 03ffe27..22c471fb 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -81,7 +81,7 @@
           'supported when --aot and --minimal-kernel are not used.',
       defaultsTo: null);
   args.addFlag('compact-async',
-      help: 'Enable new compact async/await implementation.', defaultsTo: true);
+      help: 'Enable new compact async/await implementation.', defaultsTo: null);
   args.addOption('depfile', help: 'Path to output Ninja depfile');
   args.addOption('from-dill',
       help: 'Read existing dill file instead of compiling from sources',
@@ -202,7 +202,7 @@
   final String? manifestFilename = options['manifest'];
   final String? dataDir = options['component-name'] ?? options['data-dir'];
   final bool? supportMirrors = options['support-mirrors'];
-  final bool compactAsync = options['compact-async'];
+  final bool compactAsync = options['compact-async'] ?? aot;
 
   final bool minimalKernel = options['minimal-kernel'];
   final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
@@ -617,7 +617,7 @@
     {bool trackWidgetCreation = false,
     bool nullSafety = false,
     bool supportMirrors = true,
-    bool compactAsync = true}) {
+    bool compactAsync = false}) {
   // Make sure VM-specific targets are available.
   installAdditionalTargets();
 
diff --git a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
index e0c0bdd..ec6468f 100644
--- a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
+++ b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
@@ -45,16 +45,62 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/a.dart" as a;
 
-  static method j() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("J");
+  static method j() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    dynamic :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L1:
+        {
+          dart.core::print("J");
+        }
+        dart.async::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library h from "#pkg/vm/testcases/transformations/deferred_loading/h.dart" as h {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" as g;
 
-  static method h() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("H");
+  static method h() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    dynamic :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L2:
+        {
+          dart.core::print("H");
+        }
+        dart.async::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library i from "#pkg/vm/testcases/transformations/deferred_loading/i.dart" as i {
@@ -62,18 +108,67 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/j.dart" deferred as j;
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b;
 
-  static method i() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("I");
-    await LoadLibrary(j);
-    return let final dynamic #t1 = CheckLibraryIsLoaded(j) in j::j();
+  static method i() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L3:
+        {
+          dart.core::print("I");
+          [yield] let dynamic #t1 = dart.async::_awaitHelper(LoadLibrary(j), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t2 = CheckLibraryIsLoaded(j) in j::j();
+          break #L3;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library g from "#pkg/vm/testcases/transformations/deferred_loading/g.dart" as g {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/h.dart" as h;
 
-  static method g() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("G");
+  static method g() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    dynamic :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L4:
+        {
+          dart.core::print("G");
+        }
+        dart.async::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library f from "#pkg/vm/testcases/transformations/deferred_loading/f.dart" as f {
@@ -81,22 +176,76 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" deferred as g;
   import "#pkg/vm/testcases/transformations/deferred_loading/i.dart" deferred as i;
 
-  static method f() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("F");
-    await LoadLibrary(g);
-    return let final dynamic #t2 = CheckLibraryIsLoaded(g) in g::g();
-    await LoadLibrary(i);
-    return let final dynamic #t3 = CheckLibraryIsLoaded(i) in i::i();
+  static method f() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L5:
+        {
+          dart.core::print("F");
+          [yield] let dynamic #t3 = dart.async::_awaitHelper(LoadLibrary(g), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t4 = CheckLibraryIsLoaded(g) in g::g();
+          break #L5;
+          [yield] let dynamic #t5 = dart.async::_awaitHelper(LoadLibrary(i), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t6 = CheckLibraryIsLoaded(i) in i::i();
+          break #L5;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library e from "#pkg/vm/testcases/transformations/deferred_loading/e.dart" as e {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" deferred as g;
 
-  static method e() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("E");
-    await LoadLibrary(g);
-    return let final dynamic #t4 = CheckLibraryIsLoaded(g) in g::g();
+  static method e() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L6:
+        {
+          dart.core::print("E");
+          [yield] let dynamic #t7 = dart.async::_awaitHelper(LoadLibrary(g), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t8 = CheckLibraryIsLoaded(g) in g::g();
+          break #L6;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library c from "#pkg/vm/testcases/transformations/deferred_loading/c.dart" as c {
@@ -104,38 +253,138 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b;
   import "#pkg/vm/testcases/transformations/deferred_loading/f.dart" deferred as f;
 
-  static method c() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("C");
-    await LoadLibrary(f);
-    return let final dynamic #t5 = CheckLibraryIsLoaded(f) in f::f();
+  static method c() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L7:
+        {
+          dart.core::print("C");
+          [yield] let dynamic #t9 = dart.async::_awaitHelper(LoadLibrary(f), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t10 = CheckLibraryIsLoaded(f) in f::f();
+          break #L7;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library d from "#pkg/vm/testcases/transformations/deferred_loading/d.dart" as d {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/e.dart" as e;
 
-  static method d() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("D");
-    return e::e();
+  static method d() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L8:
+        {
+          dart.core::print("D");
+          :return_value = e::e();
+          break #L8;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library b from "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/c.dart" as c;
 
-  static method b() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("B");
-    return c::c();
+  static method b() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L9:
+        {
+          dart.core::print("B");
+          :return_value = c::c();
+          break #L9;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library a from "#pkg/vm/testcases/transformations/deferred_loading/a.dart" as a {
 
   import "#pkg/vm/testcases/transformations/deferred_loading/d.dart" deferred as d;
 
-  static method a() → dynamic async /* futureValueType= dynamic */ {
-    dart.core::print("A");
-    await LoadLibrary(d);
-    return let final dynamic #t6 = CheckLibraryIsLoaded(d) in d::d();
+  static method a() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L10:
+        {
+          dart.core::print("A");
+          [yield] let dynamic #t11 = dart.async::_awaitHelper(LoadLibrary(d), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          :return_value = let final dynamic #t12 = CheckLibraryIsLoaded(d) in d::d();
+          break #L10;
+        }
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
 library #lib from "#lib" as #lib {
@@ -143,8 +392,34 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/a.dart";
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart";
 
-  static method main() → dynamic async /* futureValueType= dynamic */ {
-    await a::a();
-    await b::b();
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+    final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
+    dynamic :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (dart.core::Object, dart.core::StackTrace) → dynamic :async_op_error;
+    dart.core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L11:
+        {
+          [yield] let dynamic #t13 = dart.async::_awaitHelper(a::a(), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+          [yield] let dynamic #t14 = dart.async::_awaitHelper(b::b(), :async_op_then, :async_op_error) in null;
+          :result_or_exception;
+        }
+        dart.async::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, dart.core::StackTrace stack_trace) {
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
 }
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
index 2039db0..2adb29e 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
@@ -11,20 +11,70 @@
   synthetic constructor •() → self::MyFinalizable
     : super core::Object::•()
     ;
-  method use() → asy::Future<core::int> async /* futureValueType= core::int */ {
-    return block {
-      final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
-      _in::reachabilityFence(this);
-    } =>:expressionValueWrappedFinalizable;
+  method use() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
+    FutureOr<core::int>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
+    core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = block {
+            final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
+            _in::reachabilityFence(this);
+          } =>:expressionValueWrappedFinalizable;
+          break #L1;
+        }
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
-  method use2() → asy::Future<core::int> async /* futureValueType= core::int */ {
-    return block {
-      final core::int :expressionValueWrappedFinalizable = await block {
-        final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
-        _in::reachabilityFence(this);
-      } =>:expressionValueWrappedFinalizable;
-      _in::reachabilityFence(this);
-    } =>:expressionValueWrappedFinalizable;
+  method use2() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
+    core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper( block {
+            final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
+            _in::reachabilityFence(this);
+          } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+          final core::int :expressionValueWrappedFinalizable = _in::unsafeCast<core::int>(:result_or_exception);
+          :return_value = block {
+            _in::reachabilityFence(this);
+          } =>:expressionValueWrappedFinalizable;
+          break #L2;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
   }
   method use3() → asy::Future<core::int> {
     return block {
@@ -33,39 +83,117 @@
     } =>:expressionValueWrappedFinalizable;
   }
 }
-static method doSomething() → asy::Future<core::int> async /* futureValueType= core::int */ 
-  return 3;
-static method useFinalizableAsync(ffi::Finalizable finalizable) → asy::Future<core::int> async /* futureValueType= core::int */ {
-  await block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 6);
-    _in::reachabilityFence(finalizable);
-  } =>:expressionValueWrappedFinalizable;
-  final self::MyFinalizable finalizable2 = new self::MyFinalizable::•();
-  await block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 5);
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-  } =>:expressionValueWrappedFinalizable;
-  final self::MyFinalizable finalizable3 = new self::MyFinalizable::•();
-  await block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 4);
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-    _in::reachabilityFence(finalizable3);
-  } =>:expressionValueWrappedFinalizable;
-  return block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-    _in::reachabilityFence(finalizable3);
-  } =>:expressionValueWrappedFinalizable;
+static method doSomething() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
+  final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+  core::bool* :is_sync = false;
+  core::int? :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L3:
+      {
+        :return_value = 3;
+        break #L3;
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
 }
-static method main() → void async /* futureValueType= void */ {
-  final self::MyFinalizable finalizable = new self::MyFinalizable::•();
-  final asy::Future<core::int> asyncResult = self::useFinalizableAsync(finalizable);
-  core::print(await block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = asyncResult;
-    _in::reachabilityFence(finalizable);
-  } =>:expressionValueWrappedFinalizable);
-  _in::reachabilityFence(finalizable);
+static method useFinalizableAsync(ffi::Finalizable finalizable) → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
+  final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+  core::bool* :is_sync = false;
+  FutureOr<core::int>? :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L4:
+      {
+        [yield] let dynamic #t2 = asy::_awaitHelper( block {
+          final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 6);
+          _in::reachabilityFence(finalizable);
+        } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+        _in::unsafeCast<core::int>(:result_or_exception);
+        final self::MyFinalizable finalizable2 = new self::MyFinalizable::•();
+        [yield] let dynamic #t3 = asy::_awaitHelper( block {
+          final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 5);
+          _in::reachabilityFence(finalizable);
+          _in::reachabilityFence(finalizable2);
+        } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+        _in::unsafeCast<core::int>(:result_or_exception);
+        final self::MyFinalizable finalizable3 = new self::MyFinalizable::•();
+        [yield] let dynamic #t4 = asy::_awaitHelper( block {
+          final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 4);
+          _in::reachabilityFence(finalizable);
+          _in::reachabilityFence(finalizable2);
+          _in::reachabilityFence(finalizable3);
+        } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+        _in::unsafeCast<core::int>(:result_or_exception);
+        :return_value = block {
+          final asy::Future<core::int> :expressionValueWrappedFinalizable = self::doSomething();
+          _in::reachabilityFence(finalizable);
+          _in::reachabilityFence(finalizable2);
+          _in::reachabilityFence(finalizable3);
+        } =>:expressionValueWrappedFinalizable;
+        break #L4;
+      }
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
+}
+static method main() → void /* futureValueType= void */ /* originally async */ {
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
+  dynamic :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L5:
+      {
+        final self::MyFinalizable finalizable = new self::MyFinalizable::•();
+        final asy::Future<core::int> asyncResult = self::useFinalizableAsync(finalizable);
+        [yield] let dynamic #t5 = asy::_awaitHelper( block {
+          final asy::Future<core::int> :expressionValueWrappedFinalizable = asyncResult;
+          _in::reachabilityFence(finalizable);
+        } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+        core::print(_in::unsafeCast<core::int>(:result_or_exception));
+        _in::reachabilityFence(finalizable);
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
index e3d7376..74e5fe6 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
@@ -14,58 +14,128 @@
 }
 static method doSomething() → core::int
   return 3;
-static method useFinalizableAsyncStar(ffi::Finalizable finalizable) → asy::Stream<core::int> async* {
-  final self::MyFinalizable finalizable2 = new self::MyFinalizable::•();
-  yield block {
-    final core::int :expressionValueWrappedFinalizable = self::doSomething();
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-  } =>:expressionValueWrappedFinalizable;
-  final self::MyFinalizable finalizable3 = new self::MyFinalizable::•();
-  await block {
-    final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 3);
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-    _in::reachabilityFence(finalizable3);
-  } =>:expressionValueWrappedFinalizable;
-  final self::MyFinalizable finalizable4 = new self::MyFinalizable::•();
-  if(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}{core::int} =={core::num::==}{(core::Object) → core::bool} 4) {
-    {
-      _in::reachabilityFence(finalizable);
-      _in::reachabilityFence(finalizable2);
-      _in::reachabilityFence(finalizable3);
-      _in::reachabilityFence(finalizable4);
+static method useFinalizableAsyncStar(ffi::Finalizable finalizable) → asy::Stream<core::int> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::int>? :controller;
+  dynamic :controller_stream;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try
+      try {
+        #L1:
+        {
+          final self::MyFinalizable finalizable2 = new self::MyFinalizable::•();
+          if([@vm.call-site-attributes.metadata=receiverType:dart.async::_AsyncStarStreamController<dart.core::int>?] :controller.{asy::_AsyncStarStreamController::add}( block {
+            final core::int :expressionValueWrappedFinalizable = self::doSomething();
+            _in::reachabilityFence(finalizable);
+            _in::reachabilityFence(finalizable2);
+          } =>:expressionValueWrappedFinalizable){(core::int) → core::bool})
+            return null;
+          else
+            [yield] null;
+          final self::MyFinalizable finalizable3 = new self::MyFinalizable::•();
+          [yield] let dynamic #t1 = asy::_awaitHelper( block {
+            final asy::Future<core::int> :expressionValueWrappedFinalizable = asy::Future::sync<core::int>(() → core::int => 3);
+            _in::reachabilityFence(finalizable);
+            _in::reachabilityFence(finalizable2);
+            _in::reachabilityFence(finalizable3);
+          } =>:expressionValueWrappedFinalizable, :async_op_then, :async_op_error) in null;
+          _in::unsafeCast<core::int>(:result_or_exception);
+          final self::MyFinalizable finalizable4 = new self::MyFinalizable::•();
+          if(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}{core::int} =={core::num::==}{(core::Object) → core::bool} 4) {
+            {
+              _in::reachabilityFence(finalizable);
+              _in::reachabilityFence(finalizable2);
+              _in::reachabilityFence(finalizable3);
+              _in::reachabilityFence(finalizable4);
+              break #L1;
+            }
+          }
+          if([@vm.call-site-attributes.metadata=receiverType:dart.async::_AsyncStarStreamController<dart.core::int>?] :controller.{asy::_AsyncStarStreamController::add}( block {
+            final core::int :expressionValueWrappedFinalizable = 5;
+            _in::reachabilityFence(finalizable);
+            _in::reachabilityFence(finalizable2);
+            _in::reachabilityFence(finalizable3);
+            _in::reachabilityFence(finalizable4);
+          } =>:expressionValueWrappedFinalizable){(core::int) → core::bool})
+            return null;
+          else
+            [yield] null;
+          _in::reachabilityFence(finalizable2);
+          _in::reachabilityFence(finalizable3);
+          _in::reachabilityFence(finalizable4);
+          _in::reachabilityFence(finalizable);
+        }
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(exception, stack_trace){(core::Object, core::StackTrace) → void};
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}(){() → dynamic};
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::int>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::int>};
+  return :controller_stream;
+}
+static method main() → void /* futureValueType= void */ /* originally async */ {
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
+  dynamic :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L2:
+      {
+        final self::MyFinalizable finalizable = new self::MyFinalizable::•();
+        final asy::Stream<core::int> asyncStarResult = self::useFinalizableAsyncStar(finalizable);
+        {
+          asy::Stream<core::int> :stream = asyncStarResult;
+          asy::_StreamIterator<core::int>? :for-iterator = new asy::_StreamIterator::•<core::int>(:stream);
+          try
+            #L3:
+            while (true) {
+              dynamic #t2 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(){() → asy::Future<core::bool>}, :async_op_then, :async_op_error) in null;
+              if(_in::unsafeCast<core::bool>(:result_or_exception)) {
+                final core::int element = :for-iterator.{asy::_StreamIterator::current}{core::int};
+                {
+                  core::print(element);
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!(:for-iterator.{asy::_StreamIterator::_subscription}{asy::StreamSubscription<core::int>?} == null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(){() → asy::Future<dynamic>}, :async_op_then, :async_op_error) in null;
+              :result_or_exception;
+            }
+        }
+        _in::reachabilityFence(finalizable);
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
-  }
-  yield block {
-    final core::int :expressionValueWrappedFinalizable = 5;
-    _in::reachabilityFence(finalizable);
-    _in::reachabilityFence(finalizable2);
-    _in::reachabilityFence(finalizable3);
-    _in::reachabilityFence(finalizable4);
-  } =>:expressionValueWrappedFinalizable;
-  _in::reachabilityFence(finalizable2);
-  _in::reachabilityFence(finalizable3);
-  _in::reachabilityFence(finalizable4);
-  _in::reachabilityFence(finalizable);
-}
-static method main() → void async /* futureValueType= void */ {
-  final self::MyFinalizable finalizable = new self::MyFinalizable::•();
-  final asy::Stream<core::int> asyncStarResult = self::useFinalizableAsyncStar(finalizable);
-  {
-    asy::Stream<core::int> :stream = asyncStarResult;
-    asy::_StreamIterator<core::int>? :for-iterator = new asy::_StreamIterator::•<core::int>(:stream);
-    try
-      while (let dynamic #t1 = asy::_asyncStarMoveNextHelper(:stream) in await :for-iterator.{asy::_StreamIterator::moveNext}(){() → asy::Future<core::bool>}) {
-        final core::int element = :for-iterator.{asy::_StreamIterator::current}{core::int};
-        {
-          core::print(element);
-        }
-      }
-    finally
-      if(!(:for-iterator.{asy::_StreamIterator::_subscription}{asy::StreamSubscription<core::int>?} == null))
-        await :for-iterator.{asy::_StreamIterator::cancel}(){() → asy::Future<dynamic>};
-  }
-  _in::reachabilityFence(finalizable);
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/vm/testcases/transformations/ffi/regress_49075.dart.expect b/pkg/vm/testcases/transformations/ffi/regress_49075.dart.expect
index fb88d53..2974867 100644
--- a/pkg/vm/testcases/transformations/ffi/regress_49075.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/regress_49075.dart.expect
@@ -14,7 +14,32 @@
     _in::reachabilityFence(this);
   }
 }
-static method main(core::List<core::String> arguments) → asy::Future<void> async /* futureValueType= void */ {
-  final self::MyFinalizable myFinalizable = await new self::MyFinalizable::•();
-  _in::reachabilityFence(myFinalizable);
+static method main(core::List<core::String> arguments) → asy::Future<void> /* futureValueType= void */ /* originally async */ {
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
+  void :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L1:
+      {
+        [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFinalizable::•(), :async_op_then, :async_op_error) in null;
+        final self::MyFinalizable myFinalizable = _in::unsafeCast<self::MyFinalizable>(:result_or_exception);
+        _in::reachabilityFence(myFinalizable);
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
index da9a9a2..0d6b3b9 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -7,8 +7,33 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic> async /* futureValueType= dynamic */ 
-    return core::print(x);
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
+    final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
+    FutureOr<dynamic>? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
+    core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print(x);
+          break #L1;
+        }
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
+  }
 }
 class B extends core::Object {
   synthetic constructor •() → self::B
@@ -17,8 +42,61 @@
 }
 static method foo() → dynamic
   return new self::A::•();
-static method baz() → asy::Future<dynamic> async /* futureValueType= dynamic */ 
-  return new self::B::•();
-static method main() → dynamic async /* futureValueType= dynamic */ {
-  await [@vm.direct-call.metadata=#lib::A.bar] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::A] self::foo(){dynamic}.bar(await self::baz());
+static method baz() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
+  dynamic :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::B::•();
+        break #L2;
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
+}
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
+  dynamic :return_value;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :async_temporary_0;
+  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+    try {
+      #L3:
+      {
+        :async_temporary_0 = [@vm.inferred-type.metadata=#lib::A] self::foo();
+        [yield] let dynamic #t1 = asy::_awaitHelper([@vm.inferred-type.metadata=dart.async::_Future<dynamic>] self::baz(), :async_op_then, :async_op_error) in null;
+        [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=#lib::A.bar??] [@vm.inferred-type.metadata=dart.async::_Future<dynamic> (receiver not int)] :async_temporary_0{dynamic}.bar(:result_or_exception), :async_op_then, :async_op_error) in null;
+        :result_or_exception;
+      }
+      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+      return;
+    }
+    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+    }
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_op(null, null){() → dynamic};
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/vm_service/test/async_single_step_exception_test.dart b/pkg/vm_service/test/async_single_step_exception_test.dart
index 3a093de..2e06ba7 100644
--- a/pkg/vm_service/test/async_single_step_exception_test.dart
+++ b/pkg/vm_service/test/async_single_step_exception_test.dart
@@ -54,6 +54,10 @@
   smartNext,
 
   hasStoppedAtBreakpoint,
+  stoppedAtLine(22), // } (weird dispatching)
+  smartNext,
+
+  hasStoppedAtBreakpoint,
   stoppedAtLine(LINE_D), // await helper (weird dispatching)
   smartNext,
 
diff --git a/pkg/vm_service/test/async_single_step_out_test.dart b/pkg/vm_service/test/async_single_step_out_test.dart
index 71f9517..1db5d67 100644
--- a/pkg/vm_service/test/async_single_step_out_test.dart
+++ b/pkg/vm_service/test/async_single_step_out_test.dart
@@ -44,10 +44,14 @@
   stepInto, // exit helper via a single step.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_D), // await helper
-  smartNext,
+  stoppedAtLine(20), // return null (weird dispatching)
+  stepInto, // exit helper via a single step.
 
   hasStoppedAtBreakpoint,
+  stoppedAtLine(25), // await helper (weird dispatching)
+  smartNext,
+
+  hasStoppedAtBreakpoint, //19
   stoppedAtLine(LINE_E), // arrive after the await.
   resumeIsolate
 ];
diff --git a/pkg/vm_service/test/async_star_single_step_into_test.dart b/pkg/vm_service/test/async_star_single_step_into_test.dart
index be3eba7..bf5c964 100644
--- a/pkg/vm_service/test/async_star_single_step_into_test.dart
+++ b/pkg/vm_service/test/async_star_single_step_into_test.dart
@@ -8,13 +8,12 @@
 import 'common/service_test_common.dart';
 import 'common/test_helper.dart';
 
-const LINE_A = 20;
-const LINE_B = 21;
-const LINE_C = 25;
-const LINE_D = 29;
-const LINE_E = 35;
-const LINE_F = 36;
-const LINE_G = 27;
+const LINE_A = 19;
+const LINE_B = 20;
+const LINE_C = 24;
+const LINE_D = 28;
+const LINE_E = 34;
+const LINE_F = 35;
 
 foobar() async* {
   yield 1; // LINE_A.
@@ -24,7 +23,7 @@
 helper() async {
   print('helper'); // LINE_C.
   // ignore: unused_local_variable
-  await for (var i in foobar()) /* LINE_G. */ {
+  await for (var i in foobar()) {
     debugger();
     print('loop'); // LINE_D.
   }
@@ -51,11 +50,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // foobar()
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // await for
   stepInto,
 
   hasStoppedAtBreakpoint,
@@ -69,7 +63,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G),
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/pkg/vm_service/test/async_star_step_out_test.dart b/pkg/vm_service/test/async_star_step_out_test.dart
index 41d387f..14a05f9 100644
--- a/pkg/vm_service/test/async_star_step_out_test.dart
+++ b/pkg/vm_service/test/async_star_step_out_test.dart
@@ -54,11 +54,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // foobar().
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // await for.
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/pkg/vm_service/test/awaiter_async_stack_contents_2_test.dart b/pkg/vm_service/test/awaiter_async_stack_contents_2_test.dart
index 5cd7443..88d17d0a 100644
--- a/pkg/vm_service/test/awaiter_async_stack_contents_2_test.dart
+++ b/pkg/vm_service/test/awaiter_async_stack_contents_2_test.dart
@@ -49,9 +49,9 @@
     List<Frame> awaiterFrames = stack.awaiterFrames!;
     expect(awaiterFrames.length, greaterThanOrEqualTo(2));
     // Awaiter frame.
-    expect(awaiterFrames[0].function!.name, 'foobar');
+    expect(awaiterFrames[0].function!.owner.name, 'foobar');
     // Awaiter frame.
-    expect(awaiterFrames[1].function!.name, 'helper');
+    expect(awaiterFrames[1].function!.owner.name, 'helper');
   },
 ];
 
diff --git a/pkg/vm_service/test/awaiter_async_stack_contents_test.dart b/pkg/vm_service/test/awaiter_async_stack_contents_test.dart
index ac8ab8c..0fea350 100644
--- a/pkg/vm_service/test/awaiter_async_stack_contents_test.dart
+++ b/pkg/vm_service/test/awaiter_async_stack_contents_test.dart
@@ -56,9 +56,9 @@
 
     expect(awaiterFrames.length, greaterThanOrEqualTo(2));
     // Awaiter frame.
-    expect(await awaiterFrames[0].function!.name, 'foobar');
+    expect(await awaiterFrames[0].function!.owner.name, 'foobar');
     // Awaiter frame.
-    expect(await awaiterFrames[1].function!.name, 'helper');
+    expect(await awaiterFrames[1].function!.owner.name, 'helper');
     // "helper" is not await'ed.
   },
 ];
diff --git a/pkg/vm_service/test/causal_async_stack_contents_test.dart b/pkg/vm_service/test/causal_async_stack_contents_test.dart
index b28ece5..b634f10 100644
--- a/pkg/vm_service/test/causal_async_stack_contents_test.dart
+++ b/pkg/vm_service/test/causal_async_stack_contents_test.dart
@@ -48,7 +48,7 @@
     // Has causal frames (we are inside an async function)
     expect(stack.asyncCausalFrames, isNotNull);
     expect(
-      stack.asyncCausalFrames![0].function!.name,
+      stack.asyncCausalFrames![0].function!.owner.name,
       contains('helper'),
     );
     // "helper" is not await'ed.
@@ -62,7 +62,7 @@
     expect(stack.asyncCausalFrames, isNotNull);
     final asyncStack = stack.asyncCausalFrames!;
     expect(asyncStack[0].function!.name, contains('foobar'));
-    expect(asyncStack[1].function!.name, contains('helper'));
+    expect(asyncStack[1].function!.owner.name, contains('helper'));
     // "helper" is not await'ed.
   },
 ];
diff --git a/pkg/vm_service/test/causal_async_star_stack_contents_test.dart b/pkg/vm_service/test/causal_async_star_stack_contents_test.dart
index 80f0a2d..4795850 100644
--- a/pkg/vm_service/test/causal_async_star_stack_contents_test.dart
+++ b/pkg/vm_service/test/causal_async_star_stack_contents_test.dart
@@ -45,7 +45,7 @@
     expect(stack.asyncCausalFrames, isNotNull);
     final asyncStack = stack.asyncCausalFrames!;
     expect(asyncStack.length, greaterThanOrEqualTo(1));
-    expect(asyncStack[0].function!.name, contains('helper'));
+    expect(asyncStack[0].function!.owner.name, contains('helper'));
     // helper isn't awaited.
   },
   resumeIsolate,
@@ -57,9 +57,9 @@
     expect(stack.asyncCausalFrames, isNotNull);
     final asyncStack = stack.asyncCausalFrames!;
     expect(asyncStack.length, greaterThanOrEqualTo(3));
-    expect(asyncStack[0].function!.name, contains('foobar'));
+    expect(asyncStack[0].function!.owner.name, contains('foobar'));
     expect(asyncStack[1].kind, equals(FrameKind.kAsyncSuspensionMarker));
-    expect(asyncStack[2].function!.name, contains('helper'));
+    expect(asyncStack[2].function!.owner.name, contains('helper'));
     expect(asyncStack[3].kind, equals(FrameKind.kAsyncSuspensionMarker));
   },
   resumeIsolate,
@@ -73,13 +73,13 @@
     expect(asyncStack.length, greaterThanOrEqualTo(4));
     final script = await service.getObject(
         isolateRef.id!, asyncStack[0].location!.script!.id!) as Script;
-    expect(asyncStack[0].function!.name, contains('foobar'));
+    expect(asyncStack[0].function!.owner.name, contains('foobar'));
     expect(
       script.getLineNumberFromTokenPos(asyncStack[0].location!.tokenPos!),
       LINE_C,
     );
     expect(asyncStack[1].kind, equals(FrameKind.kAsyncSuspensionMarker));
-    expect(asyncStack[2].function!.name, contains('helper'));
+    expect(asyncStack[2].function!.owner.name, contains('helper'));
     expect(
       script.getLineNumberFromTokenPos(asyncStack[2].location!.tokenPos!),
       30,
diff --git a/pkg/vm_service/test/coverage_const_field_async_closure_test.dart b/pkg/vm_service/test/coverage_const_field_async_closure_test.dart
index 8bdb959..8a7430d 100644
--- a/pkg/vm_service/test/coverage_const_field_async_closure_test.dart
+++ b/pkg/vm_service/test/coverage_const_field_async_closure_test.dart
@@ -41,7 +41,7 @@
     // Make sure we are in the right place.
     expect(stack.frames!.length, greaterThanOrEqualTo(1));
     // Async closure of testFunction
-    expect(stack.frames![0].function!.name, 'testFunction');
+    expect(stack.frames![0].function!.name, 'async_op');
 
     final rootLib =
         await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
diff --git a/pkg/vm_service/test/rpc_error_test.dart b/pkg/vm_service/test/rpc_error_test.dart
index 67330c2..87e8776 100644
--- a/pkg/vm_service/test/rpc_error_test.dart
+++ b/pkg/vm_service/test/rpc_error_test.dart
@@ -17,9 +17,9 @@
       // Ensure stack trace contains actual invocation path.
       final stack = st.toString().split('\n');
       expect(stack.where((e) => e.contains('VmService.callMethod')).length, 1);
-      // Call to vm.callMethod('foo').
+      // Call to vm.callMethod('foo') and the invocation of the test closure.
       expect(
-          stack.where((e) => e.contains('test/rpc_error_test.dart')).length, 1);
+          stack.where((e) => e.contains('test/rpc_error_test.dart')).length, 2);
     } catch (e) {
       fail('Expected RPCError, got $e');
     }
diff --git a/pkg/vm_service/test/server_test.dart b/pkg/vm_service/test/server_test.dart
index db0f7e8..6cf1c38 100644
--- a/pkg/vm_service/test/server_test.dart
+++ b/pkg/vm_service/test/server_test.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.10
-
 @TestOn('vm')
 import 'dart:async';
 import 'dart:convert';
@@ -14,15 +12,15 @@
 import 'package:vm_service/vm_service.dart';
 
 void main() {
-  MockVmService serviceMock;
-  StreamController<Map<String, Object>> requestsController;
-  StreamController<Map<String, Object>> responsesController;
-  ServiceExtensionRegistry serviceRegistry;
+  late MockVmService serviceMock;
+  late StreamController<Map<String, Object>> requestsController;
+  late StreamController<Map<String, Object?>> responsesController;
+  late ServiceExtensionRegistry serviceRegistry;
 
   setUp(() {
     serviceMock = MockVmService();
     requestsController = StreamController<Map<String, Object>>();
-    responsesController = StreamController<Map<String, Object>>();
+    responsesController = StreamController<Map<String, Object?>>();
     serviceRegistry = ServiceExtensionRegistry();
     VmServerConnection(requestsController.stream, responsesController.sink,
         serviceRegistry, serviceMock);
@@ -41,7 +39,6 @@
       expect(responsesController.stream, emits(rpcResponse(version)));
       requestsController.add(request);
     });
-
     test('works for methods with parameters', () {
       var isolate = Isolate(
         name: 'isolate',
@@ -61,8 +58,9 @@
         breakpoints: [],
         isSystemIsolate: false,
       );
-      var request = rpcRequest("getIsolate", params: {'isolateId': isolate.id});
-      when(serviceMock.getIsolate(isolate.id))
+      var request =
+          rpcRequest("getIsolate", params: {'isolateId': isolate.id!});
+      when(serviceMock.getIsolate(isolate.id!))
           .thenAnswer((Invocation invocation) {
         expect(invocation.positionalArguments, equals([isolate.id]));
         return Future.value(isolate);
@@ -91,13 +89,13 @@
         isSystemIsolate: false,
       );
       var request = rpcRequest("setVMTimelineFlags", params: {
-        'isolateId': isolate.id,
+        'isolateId': isolate.id!,
         // Note: the dynamic list below is intentional in order to exercise the
         // code under test.
         'recordedStreams': <dynamic>['GC', 'Dart', 'Embedder'],
       });
       var response = Success();
-      when(serviceMock.getIsolate(isolate.id))
+      when(serviceMock.getIsolate(isolate.id!))
           .thenAnswer((Invocation invocation) {
         expect(invocation.namedArguments,
             equals({Symbol('isolateId'): null, Symbol('args'): null}));
@@ -217,7 +215,7 @@
         requestsController.add(request);
         await expectLater(responseQueue, emitsThrough(rpcResponse(response)));
 
-        eventController = serviceMock.streamControllers[streamId];
+        eventController = serviceMock.streamControllers[streamId]!;
 
         var events = [
           Event(
@@ -338,7 +336,7 @@
         // Connect another client to get the previous register events and the
         // unregister event.
         var requestsController2 = StreamController<Map<String, Object>>();
-        var responsesController2 = StreamController<Map<String, Object>>();
+        var responsesController2 = StreamController<Map<String, Object?>>();
         addTearDown(() {
           requestsController2.close();
           responsesController2.close();
@@ -370,7 +368,7 @@
         // Connect yet another client, it should get zero registration or
         // unregistration events.
         var requestsController3 = StreamController<Map<String, Object>>();
-        var responsesController3 = StreamController<Map<String, Object>>();
+        var responsesController3 = StreamController<Map<String, Object?>>();
 
         VmServerConnection(
           requestsController3.stream,
@@ -397,11 +395,13 @@
       var responseQueue = StreamQueue(responsesController.stream);
 
       var clientInputController =
-          StreamController<Map<String, Object>>.broadcast();
+          StreamController<Map<String, Object?>>.broadcast();
       var clientOutputController =
           StreamController<Map<String, Object>>.broadcast();
-      var client = VmService(clientInputController.stream.map(jsonEncode),
-          (String message) => clientOutputController.add(jsonDecode(message)),
+      var client = VmService(
+          clientInputController.stream.map(jsonEncode),
+          (String message) => clientOutputController
+              .add(jsonDecode(message).cast<String, Object>()),
           disposeHandler: () async {
         await clientInputController.close();
         await clientOutputController.close();
@@ -446,11 +446,11 @@
 }
 
 Map<String, Object> rpcRequest(String method,
-        {Map<String, Object> params = const {}, String id = "1"}) =>
+        {Map<String, Object>? params = const {}, String id = "1"}) =>
     {
       "jsonrpc": "2.0",
       "method": method,
-      "params": params,
+      if (params != null) "params": params,
       "id": id,
     };
 
@@ -468,7 +468,7 @@
       'message': error.message,
     };
     if (error.data != null) {
-      errorJson['data'] = error.data;
+      errorJson['data'] = error.data!;
     }
   } else {
     errorJson = {
@@ -494,18 +494,61 @@
   };
 }
 
-Map<String, Object> stripEventTimestamp(Map response) {
+Map<String, Object?> stripEventTimestamp(Map response) {
   if (response.containsKey('params') &&
       response['params'].containsKey('event')) {
     response['params']['event']['timestamp'] = 0;
   }
-  return response as Map<String, Object>;
+  return response as Map<String, Object?>;
 }
 
 class MockVmService extends Mock implements VmServiceInterface {
   final streamControllers = <String, StreamController<Event>>{};
 
   @override
+  Future<Version> getVersion() {
+    return super.noSuchMethod(Invocation.method(#getVersion, []),
+        returnValue: Future.value(Version(major: 0, minor: 0)));
+  }
+
+  @override
+  Future<Isolate> getIsolate(String isolateId) {
+    return super.noSuchMethod(Invocation.method(#getIsolate, [isolateId]),
+        returnValue: Future.value(Isolate(
+            id: null,
+            number: null,
+            name: null,
+            isSystemIsolate: null,
+            isolateFlags: null,
+            startTime: null,
+            runnable: null,
+            livePorts: null,
+            pauseOnExit: null,
+            pauseEvent: null,
+            libraries: null,
+            breakpoints: null,
+            exceptionPauseMode: null)));
+  }
+
+  @override
+  Future<Response> callServiceExtension(
+    String method, {
+    String? isolateId,
+    Map<String, dynamic>? args,
+  }) {
+    return super.noSuchMethod(
+        Invocation.method(#callServiceExtension, [method],
+            {#isolateId: isolateId, #args: args}),
+        returnValue: Future.value(Response()));
+  }
+
+  @override
+  Future<Success> streamListen(String streamId) {
+    return super.noSuchMethod(Invocation.method(#streamListen, [streamId]),
+        returnValue: Future.value(Success()));
+  }
+
+  @override
   Stream<Event> onEvent(String streamId) => streamControllers
       .putIfAbsent(streamId, () => StreamController<Event>())
       .stream;
diff --git a/pkg/vm_service/test/throws_sentinel_test.dart b/pkg/vm_service/test/throws_sentinel_test.dart
index bf52549..b9242b3 100644
--- a/pkg/vm_service/test/throws_sentinel_test.dart
+++ b/pkg/vm_service/test/throws_sentinel_test.dart
@@ -16,10 +16,10 @@
       // Ensure stack trace contains actual invocation path.
       final stack = st.toString().split('\n');
       expect(stack.where((e) => e.contains('VmService.getIsolate')).length, 1);
-      // Call to vm.getIsolate('isolates/12321').
+      // Call to vm.getIsolate('isolates/12321') and the invocation of the test closure.
       expect(
         stack.where((e) => e.contains('test/throws_sentinel_test.dart')).length,
-        1,
+        2,
       );
     } catch (e) {
       fail('Expected SentinelException, got $e');
diff --git a/runtime/observatory/tests/service/async_single_step_exception_test.dart b/runtime/observatory/tests/service/async_single_step_exception_test.dart
index 544ba6f..0fdc183 100644
--- a/runtime/observatory/tests/service/async_single_step_exception_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_exception_test.dart
@@ -55,6 +55,10 @@
   smartNext,
 
   hasStoppedAtBreakpoint,
+  stoppedAtLine(23), // } (weird dispatching)
+  smartNext,
+
+  hasStoppedAtBreakpoint,
   stoppedAtLine(LINE_D), // await helper (weird dispatching)
   smartNext,
 
diff --git a/runtime/observatory/tests/service/async_single_step_out_test.dart b/runtime/observatory/tests/service/async_single_step_out_test.dart
index e93c274..cfeac6c 100644
--- a/runtime/observatory/tests/service/async_single_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_out_test.dart
@@ -44,7 +44,11 @@
   stepInto, // exit helper via a single step.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_D), // await helper
+  stoppedAtLine(20), // return null (weird dispatching)
+  stepInto, // exit helper via a single step.
+
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(25), // await helper (weird dispatching)
   smartNext,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/async_star_single_step_into_test.dart b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
index ac8e6ba..0d99fd5 100644
--- a/runtime/observatory/tests/service/async_star_single_step_into_test.dart
+++ b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
@@ -8,13 +8,12 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-const LINE_A = 20;
-const LINE_B = 21;
-const LINE_C = 25;
-const LINE_D = 28;
-const LINE_E = 34;
-const LINE_F = 35;
-const LINE_G = 26;
+const LINE_A = 19;
+const LINE_B = 20;
+const LINE_C = 24;
+const LINE_D = 27;
+const LINE_E = 33;
+const LINE_F = 34;
 
 foobar() async* {
   yield 1; // LINE_A.
@@ -23,7 +22,7 @@
 
 helper() async {
   print('helper'); // LINE_C.
-  await for (var i in foobar()) /* LINE_G. */ {
+  await for (var i in foobar()) {
     debugger();
     print('loop'); // LINE_D.
   }
@@ -50,11 +49,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // foobar()
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // await for
   stepInto,
 
   hasStoppedAtBreakpoint,
@@ -68,7 +62,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G),
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/async_star_step_out_test.dart b/runtime/observatory/tests/service/async_star_step_out_test.dart
index 6e73174..95ca280 100644
--- a/runtime/observatory/tests/service/async_star_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_star_step_out_test.dart
@@ -53,11 +53,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // foobar().
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // await for.
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/coverage_const_field_async_closure_test.dart b/runtime/observatory/tests/service/coverage_const_field_async_closure_test.dart
index d3faadb..957251b 100644
--- a/runtime/observatory/tests/service/coverage_const_field_async_closure_test.dart
+++ b/runtime/observatory/tests/service/coverage_const_field_async_closure_test.dart
@@ -36,7 +36,8 @@
     // Make sure we are in the right place.
     expect(stack.type, 'Stack');
     expect(stack['frames'].length, greaterThanOrEqualTo(1));
-    expect(stack['frames'][0].function.name, 'testFunction');
+    // Async closure of testFunction
+    expect(stack['frames'][0].function.name, 'async_op');
 
     var root = isolate.rootLibrary;
     await root.load();
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index 7c87aa6..a1d5206 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, greaterThanOrEqualTo(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, greaterThanOrEqualTo(10));
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
index b3e47e2..09186aa 100644
--- a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
@@ -58,9 +58,9 @@
     expect(awaiterFrames.length, greaterThan(frames.length));
     expect(stack['truncated'], false);
     verifyStack(frames, [
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
       '_RootZone.runUnary', // Internal async. mech. ..
     ]);
 
@@ -78,9 +78,9 @@
     expect(awaiterFrames.length, fullStackLength + 1);
     expect(stack['truncated'], true);
     verifyStack(frames, [
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
       '_RootZone.runUnary', // Internal async. mech. ..
     ]);
 
@@ -96,16 +96,16 @@
     expect(awaiterFrames.length, 10);
     expect(stack['truncated'], true);
     verifyStack(frames, [
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
     ]);
   },
 // Invalid limit
diff --git a/runtime/observatory/tests/service/network_profiling_test.dart b/runtime/observatory/tests/service/network_profiling_test.dart
index 6770c58..3a318ca 100644
--- a/runtime/observatory/tests/service/network_profiling_test.dart
+++ b/runtime/observatory/tests/service/network_profiling_test.dart
@@ -24,8 +24,6 @@
 const String kStartSocketProfilingRPC = 'ext.dart.io.startSocketProfiling';
 const String localhost = '127.0.0.1';
 
-List<Object> sockets = [];
-
 Future<void> setup() async {}
 
 Future<void> socketTest() async {
@@ -56,11 +54,6 @@
   await doneCompleter.future;
   // Post finish event
   postEvent('socketTest', {'socket': 'test'});
-  // Workaround for dartbug.com/49111: make sure socket IDs are not reused.
-  sockets.add(serverSocket);
-  sockets.add(socket);
-  sockets.add(server);
-  sockets.add(client);
 }
 
 bool checkFinishEvent(ServiceEvent event) {
diff --git a/runtime/observatory/tests/service/positive_token_pos_test.dart b/runtime/observatory/tests/service/positive_token_pos_test.dart
index 6ebfbae..b9c25a8 100644
--- a/runtime/observatory/tests/service/positive_token_pos_test.dart
+++ b/runtime/observatory/tests/service/positive_token_pos_test.dart
@@ -29,7 +29,7 @@
     // We used to return a negative token position for this frame.
     // See issue #27128.
     var frame = stack['frames'][0];
-    expect(frame.function.qualifiedName, equals('helper'));
+    expect(frame.function.qualifiedName, equals('helper.async_op'));
     expect(await frame.location.getLine(), equals(14));
     expect(await frame.location.getColumn(), equals(1));
 
diff --git a/runtime/observatory/tests/service/regress_28443_test.dart b/runtime/observatory/tests/service/regress_28443_test.dart
index c986dd5..ccdec12 100644
--- a/runtime/observatory/tests/service/regress_28443_test.dart
+++ b/runtime/observatory/tests/service/regress_28443_test.dart
@@ -8,7 +8,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:test/test.dart';
 
-const int LINE_A = 28, LINE_B = 33, LINE_C = 37;
+const int LINE_A = 28, LINE_B = 33;
 
 class VMServiceClient {
   VMServiceClient(this.x);
@@ -30,11 +30,11 @@
   });
 }
 
-test_code() async /* LINE_B */ {
+test_code() async {
   try {
     await collect();
   } on TimeoutException {
-    print("ok"); // LINE_C
+    print("ok");
   }
 }
 
@@ -44,15 +44,12 @@
   setBreakpointAtLine(LINE_B),
   resumeIsolate,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_B),
   setBreakpointAtLine(LINE_A),
   resumeIsolate,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_A),
-  setBreakpointAtLine(LINE_C),
   stepOut,
-  resumeIsolate,
-  stoppedAtLine(LINE_C),
+  stoppedAtLine(LINE_B),
+  resumeIsolate
 ];
 
 main(args) => runIsolateTestsSynchronous(args, tests,
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 50afe39..0189540 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -305,7 +305,8 @@
   };
 }
 
-IsolateTest stoppedInFunction(String functionName) {
+IsolateTest stoppedInFunction(String functionName,
+    {bool contains: false, bool includeOwner: false}) {
   return (Isolate isolate) async {
     print("Checking we are in function: $functionName");
 
@@ -319,7 +320,13 @@
     ServiceFunction function =
         await topFrame.function!.load() as ServiceFunction;
     String name = function.name!;
-    final bool matches = name == functionName;
+    if (includeOwner) {
+      ServiceFunction owner =
+          await (function.dartOwner as ServiceObject).load() as ServiceFunction;
+      name = '${owner.name}.$name';
+    }
+    final bool matches =
+        contains ? name.contains(functionName) : name == functionName;
     if (!matches) {
       StringBuffer sb = new StringBuffer();
       sb.write("Expected to be in function $functionName but "
diff --git a/runtime/observatory/tests/service/set_library_debuggable_test.dart b/runtime/observatory/tests/service/set_library_debuggable_test.dart
index adac834..7431778 100644
--- a/runtime/observatory/tests/service/set_library_debuggable_test.dart
+++ b/runtime/observatory/tests/service/set_library_debuggable_test.dart
@@ -31,12 +31,12 @@
     await dartCore.reload();
     expect(dartCore.debuggable, equals(true));
   },
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_A),
   stepInto,
   stoppedInFunction('print'),
   stepOut,
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_B),
   (Isolate isolate) async {
     // Mark 'dart:core' as not debuggable.
@@ -55,10 +55,10 @@
     await dartCore.reload();
     expect(dartCore.debuggable, equals(false));
   },
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_B),
   stepInto,
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_C),
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart b/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
index 9982e0c..841afab 100644
--- a/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
@@ -55,6 +55,10 @@
   smartNext,
 
   hasStoppedAtBreakpoint,
+  stoppedAtLine(23), // } (weird dispatching)
+  smartNext,
+
+  hasStoppedAtBreakpoint,
   stoppedAtLine(LINE_D), // await helper (weird dispatching)
   smartNext,
 
diff --git a/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart b/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
index e93c274..cfeac6c 100644
--- a/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
@@ -44,7 +44,11 @@
   stepInto, // exit helper via a single step.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_D), // await helper
+  stoppedAtLine(20), // return null (weird dispatching)
+  stepInto, // exit helper via a single step.
+
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(25), // await helper (weird dispatching)
   smartNext,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart b/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
index ac8e6ba..0d99fd5 100644
--- a/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
@@ -8,13 +8,12 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-const LINE_A = 20;
-const LINE_B = 21;
-const LINE_C = 25;
-const LINE_D = 28;
-const LINE_E = 34;
-const LINE_F = 35;
-const LINE_G = 26;
+const LINE_A = 19;
+const LINE_B = 20;
+const LINE_C = 24;
+const LINE_D = 27;
+const LINE_E = 33;
+const LINE_F = 34;
 
 foobar() async* {
   yield 1; // LINE_A.
@@ -23,7 +22,7 @@
 
 helper() async {
   print('helper'); // LINE_C.
-  await for (var i in foobar()) /* LINE_G. */ {
+  await for (var i in foobar()) {
     debugger();
     print('loop'); // LINE_D.
   }
@@ -50,11 +49,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // foobar()
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G), // await for
   stepInto,
 
   hasStoppedAtBreakpoint,
@@ -68,7 +62,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_G),
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart b/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
index 6e73174..95ca280 100644
--- a/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
@@ -53,11 +53,6 @@
   stepOver, // print.
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // foobar().
-  stepInto,
-
-  hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_H), // await for.
   stepInto,
 
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory_2/tests/service_2/coverage_const_field_async_closure_test.dart b/runtime/observatory_2/tests/service_2/coverage_const_field_async_closure_test.dart
index ba084ef..f2c21ce 100644
--- a/runtime/observatory_2/tests/service_2/coverage_const_field_async_closure_test.dart
+++ b/runtime/observatory_2/tests/service_2/coverage_const_field_async_closure_test.dart
@@ -36,7 +36,8 @@
     // Make sure we are in the right place.
     expect(stack.type, 'Stack');
     expect(stack['frames'].length, greaterThanOrEqualTo(1));
-    expect(stack['frames'][0].function.name, 'testFunction');
+    // Async closure of testFunction
+    expect(stack['frames'][0].function.name, 'async_op');
 
     var root = isolate.rootLibrary;
     await root.load();
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
index 067aeba..78ea471 100644
--- a/runtime/observatory_2/tests/service_2/get_source_report_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, greaterThanOrEqualTo(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, greaterThanOrEqualTo(10));
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
index dc9f253..fca283d 100644
--- a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
@@ -58,9 +58,9 @@
     expect(awaiterFrames.length, greaterThan(frames.length));
     expect(stack['truncated'], false);
     verifyStack(frames, [
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
       '_RootZone.runUnary', // Internal async. mech. ..
     ]);
 
@@ -78,9 +78,9 @@
     expect(awaiterFrames.length, fullStackLength + 1);
     expect(stack['truncated'], true);
     verifyStack(frames, [
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
-      'bar', 'foo', 'bar', 'foo',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
       '_RootZone.runUnary', // Internal async. mech. ..
     ]);
 
@@ -96,16 +96,16 @@
     expect(awaiterFrames.length, 10);
     expect(stack['truncated'], true);
     verifyStack(frames, [
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
-      'bar',
-      'foo',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
     ]);
   },
 // Invalid limit
diff --git a/runtime/observatory_2/tests/service_2/network_profiling_test.dart b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
index 8a2053b..8ba995f 100644
--- a/runtime/observatory_2/tests/service_2/network_profiling_test.dart
+++ b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
@@ -24,8 +24,6 @@
 const String kStartSocketProfilingRPC = 'ext.dart.io.startSocketProfiling';
 const String localhost = '127.0.0.1';
 
-List<Object> sockets = [];
-
 Future<void> setup() async {}
 
 Future<void> socketTest() async {
@@ -56,11 +54,6 @@
   await doneCompleter.future;
   // Post finish event
   postEvent('socketTest', {'socket': 'test'});
-  // Workaround for dartbug.com/49111: make sure socket IDs are not reused.
-  sockets.add(serverSocket);
-  sockets.add(socket);
-  sockets.add(server);
-  sockets.add(client);
 }
 
 bool checkFinishEvent(ServiceEvent event) {
diff --git a/runtime/observatory_2/tests/service_2/positive_token_pos_test.dart b/runtime/observatory_2/tests/service_2/positive_token_pos_test.dart
index 84dc6e1..ed4d46e 100644
--- a/runtime/observatory_2/tests/service_2/positive_token_pos_test.dart
+++ b/runtime/observatory_2/tests/service_2/positive_token_pos_test.dart
@@ -29,7 +29,7 @@
     // We used to return a negative token position for this frame.
     // See issue #27128.
     var frame = stack['frames'][0];
-    expect(frame.function.qualifiedName, equals('helper'));
+    expect(frame.function.qualifiedName, equals('helper.async_op'));
     expect(await frame.location.getLine(), equals(14));
     expect(await frame.location.getColumn(), equals(1));
 
diff --git a/runtime/observatory_2/tests/service_2/regress_28443_test.dart b/runtime/observatory_2/tests/service_2/regress_28443_test.dart
index f30535f..ddc48fa 100644
--- a/runtime/observatory_2/tests/service_2/regress_28443_test.dart
+++ b/runtime/observatory_2/tests/service_2/regress_28443_test.dart
@@ -8,7 +8,7 @@
 import 'package:observatory_2/service_io.dart';
 import 'package:test/test.dart';
 
-const int LINE_A = 28, LINE_B = 33, LINE_C = 37;
+const int LINE_A = 28, LINE_B = 33;
 
 class VMServiceClient {
   VMServiceClient(this.x);
@@ -30,11 +30,11 @@
   });
 }
 
-test_code() async /* LINE_B */ {
+test_code() async {
   try {
     await collect();
   } on TimeoutException {
-    print("ok"); // LINE_C
+    print("ok");
   }
 }
 
@@ -44,15 +44,12 @@
   setBreakpointAtLine(LINE_B),
   resumeIsolate,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_B),
   setBreakpointAtLine(LINE_A),
   resumeIsolate,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(LINE_A),
-  setBreakpointAtLine(LINE_C),
   stepOut,
-  resumeIsolate,
-  stoppedAtLine(LINE_C),
+  stoppedAtLine(LINE_B),
+  resumeIsolate
 ];
 
 main(args) => runIsolateTestsSynchronous(args, tests,
diff --git a/runtime/observatory_2/tests/service_2/service_test_common.dart b/runtime/observatory_2/tests/service_2/service_test_common.dart
index a8530b0..e1dc008 100644
--- a/runtime/observatory_2/tests/service_2/service_test_common.dart
+++ b/runtime/observatory_2/tests/service_2/service_test_common.dart
@@ -308,7 +308,8 @@
   };
 }
 
-IsolateTest stoppedInFunction(String functionName) {
+IsolateTest stoppedInFunction(String functionName,
+    {bool contains: false, bool includeOwner: false}) {
   return (Isolate isolate) async {
     print("Checking we are in function: $functionName");
 
@@ -321,7 +322,13 @@
     Frame topFrame = frames[0];
     ServiceFunction function = await topFrame.function.load();
     String name = function.name;
-    final bool matches = name == functionName;
+    if (includeOwner) {
+      ServiceFunction owner =
+          await (function.dartOwner as ServiceObject).load();
+      name = '${owner.name}.$name';
+    }
+    final bool matches =
+        contains ? name.contains(functionName) : name == functionName;
     if (!matches) {
       StringBuffer sb = new StringBuffer();
       sb.write("Expected to be in function $functionName but "
diff --git a/runtime/observatory_2/tests/service_2/set_library_debuggable_test.dart b/runtime/observatory_2/tests/service_2/set_library_debuggable_test.dart
index e2bcc9c..89a8b52 100644
--- a/runtime/observatory_2/tests/service_2/set_library_debuggable_test.dart
+++ b/runtime/observatory_2/tests/service_2/set_library_debuggable_test.dart
@@ -31,12 +31,12 @@
     await dartCore.reload();
     expect(dartCore.debuggable, equals(true));
   },
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_A),
   stepInto,
   stoppedInFunction('print'),
   stepOut,
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_B),
   (Isolate isolate) async {
     // Mark 'dart:core' as not debuggable.
@@ -55,10 +55,10 @@
     await dartCore.reload();
     expect(dartCore.debuggable, equals(false));
   },
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_B),
   stepInto,
-  stoppedInFunction('testMain'),
+  stoppedInFunction('testMain', contains: true, includeOwner: true),
   stoppedAtLine(LINE_C),
 ];
 
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 584fd6d..077e9bd 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -321,12 +321,15 @@
     final expected = const <String>[
       r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
       r'^#1      noYields3 \(.*/utils.dart:54(:3)?\)$',
-      r'^#2      noYields2 \(.*/utils.dart:50(:9)?\)$',
-      r'^#3      noYields \(.*/utils.dart:46(:9)?\)$',
+      r'^#2      noYields3 \(.*/utils.dart:53(:23)?\)$',
+      r'^#3      noYields2 \(.*/utils.dart:50(:9)?\)$',
+      r'^#4      noYields2 \(.*/utils.dart:49(:23)?\)$',
+      r'^#5      noYields \(.*/utils.dart:46(:9)?\)$',
+      r'^#6      noYields \(.*/utils.dart:45(:22)?\)$',
     ];
     final postfix = const <String>[
-      r'^#5      doTestsNoCausalNoLazy ',
-      r'^#6      _RootZone.runUnary \(.+\)$',
+      r'^#9      doTestsNoCausalNoLazy ',
+      r'^#10     _RootZone.runUnary \(.+\)$',
       // The rest are internal frames which we don't really care about.
       IGNORE_REMAINING_STACK,
     ];
@@ -335,7 +338,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwait ',
+              r'^#7      doTestAwait ',
+              r'^#8      doTestAwait ',
             ] +
             postfix,
         debugInfoFilename);
@@ -344,7 +348,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwaitThen ',
+              r'^#7      doTestAwaitThen ',
+              r'^#8      doTestAwaitThen ',
             ] +
             postfix,
         debugInfoFilename);
@@ -353,7 +358,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwaitCatchError ',
+              r'^#7      doTestAwaitCatchError ',
+              r'^#8      doTestAwaitCatchError ',
             ] +
             postfix,
         debugInfoFilename);
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
index 5ae06ed..0d1489c 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -323,12 +323,15 @@
     final expected = const <String>[
       r'^#0      throwSync \(.*/utils.dart:18(:3)?\)$',
       r'^#1      noYields3 \(.*/utils.dart:56(:3)?\)$',
-      r'^#2      noYields2 \(.*/utils.dart:52(:9)?\)$',
-      r'^#3      noYields \(.*/utils.dart:48(:9)?\)$',
+      r'^#2      noYields3 \(.*/utils.dart:55(:23)?\)$',
+      r'^#3      noYields2 \(.*/utils.dart:52(:9)?\)$',
+      r'^#4      noYields2 \(.*/utils.dart:51(:23)?\)$',
+      r'^#5      noYields \(.*/utils.dart:48(:9)?\)$',
+      r'^#6      noYields \(.*/utils.dart:47(:22)?\)$',
     ];
     final postfix = const <String>[
-      r'^#5      doTestsNoCausalNoLazy ',
-      r'^#6      _RootZone.runUnary ',
+      r'^#9      doTestsNoCausalNoLazy ',
+      r'^#10     _RootZone.runUnary ',
       // The rest are internal frames which we don't really care about.
       IGNORE_REMAINING_STACK,
     ];
@@ -337,7 +340,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwait ',
+              r'^#7      doTestAwait ',
+              r'^#8      doTestAwait ',
             ] +
             postfix,
         debugInfoFilename);
@@ -346,7 +350,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwaitThen ',
+              r'^#7      doTestAwaitThen ',
+              r'^#8      doTestAwaitThen ',
             ] +
             postfix,
         debugInfoFilename);
@@ -355,7 +360,8 @@
         noYields,
         expected +
             const <String>[
-              r'^#4      doTestAwaitCatchError ',
+              r'^#7      doTestAwaitCatchError ',
+              r'^#8      doTestAwaitCatchError ',
             ] +
             postfix,
         debugInfoFilename);
diff --git a/runtime/vm/compiler/backend/yield_position_test.cc b/runtime/vm/compiler/backend/yield_position_test.cc
index edad705..c28b700 100644
--- a/runtime/vm/compiler/backend/yield_position_test.cc
+++ b/runtime/vm/compiler/backend/yield_position_test.cc
@@ -12,10 +12,11 @@
 
 namespace dart {
 
-using YieldPoints = ZoneGrowableArray<TokenPosition>;
+using Pair = std::pair<intptr_t, TokenPosition>;
+using YieldPoints = ZoneGrowableArray<Pair>;
 
-int LowestFirst(const TokenPosition* a, const TokenPosition* b) {
-  return a->Pos() - b->Pos();
+int LowestFirst(const Pair* a, const Pair* b) {
+  return a->first - b->first;
 }
 
 static YieldPoints* GetYieldPointsFromGraph(FlowGraph* flow_graph) {
@@ -24,8 +25,13 @@
   for (auto block : blocks) {
     ForwardInstructionIterator it(block);
     while (!it.Done()) {
-      if (auto suspend_instr = it.Current()->AsSuspend()) {
-        array->Add(suspend_instr->token_pos());
+      if (auto return_instr = it.Current()->AsReturn()) {
+        if (return_instr->yield_index() !=
+            UntaggedPcDescriptors::kInvalidYieldIndex) {
+          ASSERT(return_instr->yield_index() > 0);
+          array->Add(
+              Pair(return_instr->yield_index(), return_instr->token_pos()));
+        }
       }
       it.Advance();
     }
@@ -40,7 +46,7 @@
   PcDescriptors::Iterator it(pc_descriptor, UntaggedPcDescriptors::kOther);
   while (it.MoveNext()) {
     if (it.YieldIndex() != UntaggedPcDescriptors::kInvalidYieldIndex) {
-      array->Add(it.TokenPos());
+      array->Add(Pair(it.YieldIndex(), it.TokenPos()));
     }
   }
   array->Sort(LowestFirst);
@@ -69,7 +75,13 @@
   // function for the inner closure.
   Invoke(root_library, "foo");
 
-  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  const auto& outer_function =
+      Function::Handle(GetFunction(root_library, "foo"));
+
+  // Grab the inner, lazily created, closure from the object store.
+  const auto& function = Function::Handle(
+      ClosureFunctionsCache::GetUniqueInnerClosure(outer_function));
+  RELEASE_ASSERT(function.IsFunction());
 
   // Ensure we have 3 different return instructions with yield indices attached
   // to them.
@@ -81,9 +93,12 @@
   auto validate_indices = [](const YieldPoints& yield_points) {
     EXPECT_EQ(3, yield_points.length());
 
-    EXPECT_EQ(88, yield_points[0].Pos());
-    EXPECT_EQ(129, yield_points[1].Pos());
-    EXPECT_EQ(170, yield_points[2].Pos());
+    EXPECT_EQ(1, yield_points[0].first);
+    EXPECT_EQ(88, yield_points[0].second.Pos());
+    EXPECT_EQ(2, yield_points[1].first);
+    EXPECT_EQ(129, yield_points[1].second.Pos());
+    EXPECT_EQ(3, yield_points[2].first);
+    EXPECT_EQ(170, yield_points[2].second.Pos());
   };
 
   validate_indices(*GetYieldPointsFromGraph(flow_graph));
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 2badb5f..529c56d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4760,6 +4760,7 @@
     TokenPosition* position) {
   const TokenPosition pos = ReadPosition();  // read position.
   if (position != nullptr) *position = pos;
+  ReadBool();  // read exhaustive flag.
 
   // We need the number of cases. So start by getting that, then go back.
   intptr_t offset = ReaderOffset();
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 7347029..6be0574 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -714,6 +714,7 @@
       return;
     case kSwitchStatement: {
       ReadPosition();                     // read position.
+      ReadBool();                         // read exhaustive flag.
       CalculateExpressionFingerprint();   // read condition.
       int case_count = ReadListLength();  // read number of cases.
       for (intptr_t i = 0; i < case_count; ++i) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 7dba48a..b84479f 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2724,6 +2724,7 @@
       return;
     case kSwitchStatement: {
       ReadPosition();                     // read position.
+      ReadBool();                         // read exhaustive flag.
       SkipExpression();                   // read condition.
       int case_count = ReadListLength();  // read number of cases.
       for (intptr_t i = 0; i < case_count; ++i) {
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 3282161..5151145 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -1186,6 +1186,7 @@
     case kSwitchStatement: {
       AddSwitchVariable();
       helper_.ReadPosition();                     // read position.
+      helper_.ReadBool();                         // read exhaustive flag.
       VisitExpression();                          // read condition.
       int case_count = helper_.ReadListLength();  // read number of cases.
       for (intptr_t i = 0; i < case_count; ++i) {
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 68ba680..ce07e8e 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -193,7 +193,7 @@
     }
     CollectGarbage(thread, GCType::kMarkSweep, GCReason::kExternal);
   } else {
-    CheckStartConcurrentMarking(thread, GCReason::kExternal);
+    CheckConcurrentMarking(thread, GCReason::kExternal);
   }
 }
 
@@ -457,7 +457,7 @@
         CollectOldSpaceGarbage(thread, GCType::kMarkSweep,
                                GCReason::kPromotion);
       } else {
-        CheckStartConcurrentMarking(thread, GCReason::kPromotion);
+        CheckConcurrentMarking(thread, GCReason::kPromotion);
       }
     }
   }
@@ -554,29 +554,42 @@
   WaitForSweeperTasks(thread);
 }
 
-void Heap::CheckStartConcurrentMarking(Thread* thread, GCReason reason) {
+void Heap::CheckConcurrentMarking(Thread* thread, GCReason reason) {
+  PageSpace::Phase phase;
   {
     MonitorLocker ml(old_space_.tasks_lock());
-    if (old_space_.phase() != PageSpace::kDone) {
-      return;  // Busy.
-    }
+    phase = old_space_.phase();
   }
 
-  if (old_space_.ReachedSoftThreshold()) {
-    // New-space objects are roots during old-space GC. This means that even
-    // unreachable new-space objects prevent old-space objects they reference
-    // from being collected during an old-space GC. Normally this is not an
-    // issue because new-space GCs run much more frequently than old-space GCs.
-    // If new-space allocation is low and direct old-space allocation is high,
-    // which can happen in a program that allocates large objects and little
-    // else, old-space can fill up with unreachable objects until the next
-    // new-space GC. This check is the concurrent-marking equivalent to the
-    // new-space GC before synchronous-marking in CollectMostGarbage.
-    if (last_gc_was_old_space_) {
-      CollectNewSpaceGarbage(thread, GCType::kScavenge, GCReason::kFull);
-    }
-
-    StartConcurrentMarking(thread, reason);
+  switch (phase) {
+    case PageSpace::kMarking:
+      // TODO(rmacnak): Have this thread help with marking.
+    case PageSpace::kSweepingLarge:
+    case PageSpace::kSweepingRegular:
+      return;  // Busy.
+    case PageSpace::kAwaitingFinalization:
+      CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
+      return;
+    case PageSpace::kDone:
+      if (old_space_.ReachedSoftThreshold()) {
+        // New-space objects are roots during old-space GC. This means that even
+        // unreachable new-space objects prevent old-space objects they
+        // reference from being collected during an old-space GC. Normally this
+        // is not an issue because new-space GCs run much more frequently than
+        // old-space GCs. If new-space allocation is low and direct old-space
+        // allocation is high, which can happen in a program that allocates
+        // large objects and little else, old-space can fill up with unreachable
+        // objects until the next new-space GC. This check is the
+        // concurrent-marking equivalent to the new-space GC before
+        // synchronous-marking in CollectMostGarbage.
+        if (last_gc_was_old_space_) {
+          CollectNewSpaceGarbage(thread, GCType::kScavenge, GCReason::kFull);
+        }
+        StartConcurrentMarking(thread, reason);
+      }
+      return;
+    default:
+      UNREACHABLE();
   }
 }
 
@@ -595,17 +608,6 @@
 #endif
 }
 
-void Heap::CheckFinishConcurrentMarking(Thread* thread) {
-  bool ready;
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
-    ready = old_space_.phase() == PageSpace::kAwaitingFinalization;
-  }
-  if (ready) {
-    CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
-  }
-}
-
 void Heap::WaitForMarkerTasks(Thread* thread) {
   MonitorLocker ml(old_space_.tasks_lock());
   while ((old_space_.phase() == PageSpace::kMarking) ||
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 8248ee1..6a0dc2a 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -125,9 +125,8 @@
   void CollectAllGarbage(GCReason reason = GCReason::kFull,
                          bool compact = false);
 
-  void CheckStartConcurrentMarking(Thread* thread, GCReason reason);
+  void CheckConcurrentMarking(Thread* thread, GCReason reason);
   void StartConcurrentMarking(Thread* thread, GCReason reason);
-  void CheckFinishConcurrentMarking(Thread* thread);
   void WaitForMarkerTasks(Thread* thread);
   void WaitForSweeperTasks(Thread* thread);
   void WaitForSweeperTasksAtSafepoint(Thread* thread);
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 53381e2..de7a382 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -465,19 +465,6 @@
   }
 }
 
-void PageSpace::EvaluateConcurrentMarking(GrowthPolicy growth_policy) {
-  if (growth_policy != kForceGrowth) {
-    ASSERT(GrowthControlState());
-    if (heap_ != NULL) {  // Some unit tests.
-      Thread* thread = Thread::Current();
-      if (thread->CanCollectGarbage()) {
-        heap_->CheckFinishConcurrentMarking(thread);
-        heap_->CheckStartConcurrentMarking(thread, GCReason::kOldSpace);
-      }
-    }
-  }
-}
-
 uword PageSpace::TryAllocateInFreshPage(intptr_t size,
                                         FreeList* freelist,
                                         OldPage::PageType type,
@@ -485,7 +472,12 @@
                                         bool is_locked) {
   ASSERT(Heap::IsAllocatableViaFreeLists(size));
 
-  EvaluateConcurrentMarking(growth_policy);
+  if (growth_policy != kForceGrowth) {
+    ASSERT(GrowthControlState());
+    if (heap_ != nullptr) {  // Some unit tests.
+      heap_->CheckConcurrentMarking(Thread::Current(), GCReason::kOldSpace);
+    }
+  }
 
   uword result = 0;
   SpaceUsage after_allocation = GetCurrentUsage();
@@ -521,7 +513,12 @@
                                              GrowthPolicy growth_policy) {
   ASSERT(!Heap::IsAllocatableViaFreeLists(size));
 
-  EvaluateConcurrentMarking(growth_policy);
+  if (growth_policy != kForceGrowth) {
+    ASSERT(GrowthControlState());
+    if (heap_ != nullptr) {  // Some unit tests.
+      heap_->CheckConcurrentMarking(Thread::Current(), GCReason::kOldSpace);
+    }
+  }
 
   intptr_t page_size_in_words = LargePageSizeInWordsFor(size);
   if ((page_size_in_words << kWordSizeLog2) < size) {
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index fca17a2..28ee25e 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -553,8 +553,6 @@
                                     OldPage::PageType type,
                                     GrowthPolicy growth_policy);
 
-  void EvaluateConcurrentMarking(GrowthPolicy growth_policy);
-
   // Makes bump block walkable; do not call concurrently with mutator.
   void MakeIterable() const;
 
diff --git a/runtime/vm/heap/safepoint.cc b/runtime/vm/heap/safepoint.cc
index 09e0c04..9933bed 100644
--- a/runtime/vm/heap/safepoint.cc
+++ b/runtime/vm/heap/safepoint.cc
@@ -65,7 +65,7 @@
     if (heap->old_space()->ReachedHardThreshold()) {
       heap->CollectGarbage(T, GCType::kMarkSweep, GCReason::kOldSpace);
     } else {
-      heap->CheckStartConcurrentMarking(T, GCReason::kOldSpace);
+      heap->CheckConcurrentMarking(T, GCReason::kOldSpace);
     }
   }
 }
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index a6b53d4..9425afd 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -1672,12 +1672,19 @@
   return Object::null();
 }
 
-void Scavenger::TryAllocateNewTLAB(Thread* thread, intptr_t min_size) {
+void Scavenger::TryAllocateNewTLAB(Thread* thread,
+                                   intptr_t min_size,
+                                   bool can_safepoint) {
   ASSERT(heap_ != Dart::vm_isolate_group()->heap());
   ASSERT(!scavenging_);
 
   AbandonRemainingTLAB(thread);
 
+  if (can_safepoint) {
+    ASSERT(thread->no_safepoint_scope_depth() == 0);
+    heap_->CheckConcurrentMarking(thread, GCReason::kNewSpace);
+  }
+
   MutexLocker ml(&space_lock_);
   for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
     if (page->owner() != nullptr) continue;
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 9930fa8..3c1051c 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -283,7 +283,15 @@
     if (LIKELY(addr != 0)) {
       return addr;
     }
-    TryAllocateNewTLAB(thread, size);
+    TryAllocateNewTLAB(thread, size, true);
+    return TryAllocateFromTLAB(thread, size);
+  }
+  uword TryAllocateNoSafepoint(Thread* thread, intptr_t size) {
+    uword addr = TryAllocateFromTLAB(thread, size);
+    if (LIKELY(addr != 0)) {
+      return addr;
+    }
+    TryAllocateNewTLAB(thread, size, false);
     return TryAllocateFromTLAB(thread, size);
   }
   void AbandonRemainingTLAB(Thread* thread);
@@ -393,7 +401,7 @@
     thread->set_top(result + size);
     return result;
   }
-  void TryAllocateNewTLAB(Thread* thread, intptr_t size);
+  void TryAllocateNewTLAB(Thread* thread, intptr_t size, bool can_safepoint);
 
   SemiSpace* Prologue(GCReason reason);
   intptr_t ParallelScavenge(SemiSpace* from);
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 96c196d..3801578 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 = 81;
-static const uint32_t kMaxSupportedKernelFormatVersion = 81;
+static const uint32_t kMinSupportedKernelFormatVersion = 82;
+static const uint32_t kMaxSupportedKernelFormatVersion = 82;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc
index 560a7a7..979a2b4 100644
--- a/runtime/vm/object_graph_copy.cc
+++ b/runtime/vm/object_graph_copy.cc
@@ -788,7 +788,7 @@
     const uword size =
         header_size != 0 ? header_size : from.untag()->HeapSize();
     if (Heap::IsAllocatableInNewSpace(size)) {
-      const uword alloc = new_space_->TryAllocate(thread_, size);
+      const uword alloc = new_space_->TryAllocateNoSafepoint(thread_, size);
       if (alloc != 0) {
         ObjectPtr to(reinterpret_cast<UntaggedObject*>(alloc));
         fast_forward_map_.Insert(from, to, size);
@@ -1353,7 +1353,7 @@
     auto raw_from = from.ptr().untag();
     auto raw_to = to.ptr().untag();
     const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassId();
-    raw_to->length_ = raw_from->length_;
+    ASSERT(raw_to->length_ == raw_from->length_);
     raw_to->RecomputeDataField();
     const intptr_t length =
         TypedData::ElementSizeInBytes(cid) * Smi::Value(raw_from->length_);
@@ -1605,7 +1605,7 @@
     if (length == 0) return Object::null();
 
     const intptr_t size = Array::InstanceSize(length);
-    const uword array_addr = new_space_->TryAllocate(thread_, size);
+    const uword array_addr = new_space_->TryAllocateNoSafepoint(thread_, size);
     if (array_addr == 0) {
       exception_msg_ = kFastAllocationFailed;
       return Marker();
diff --git a/samples/ffi/sqlite/README.md b/samples/ffi/sqlite/README.md
index fbd5cb9..c4656df 100644
--- a/samples/ffi/sqlite/README.md
+++ b/samples/ffi/sqlite/README.md
@@ -20,25 +20,10 @@
 ## Building and Running this Sample
 
 Building and running this sample is done through pub.
-Running `pub get` and `pub run example/main` should produce the following output.
+Running `dart run example/main` should produce the following output.
 
 ```sh
-$ pub get
-Resolving dependencies... (6.8s)
-+ analyzer 0.35.4
-...
-+ yaml 2.1.15
-Downloading analyzer 0.35.4...
-Downloading kernel 0.3.14...
-Downloading front_end 0.1.14...
-Changed 47 dependencies!
-Precompiling executables... (18.0s)
-Precompiled test:test.
-
-```
-
-```
-$ pub run example/main
+$ dart run example/main
 1 Chocolade chip cookie Chocolade cookie foo
 2 Ginger cookie null 42
 3 Cinnamon roll null null
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
index a3d73bd..c262829 100644
--- a/samples/ffi/sqlite/lib/src/bindings/bindings.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -34,6 +34,10 @@
       Pointer<Utf8> vfs) sqlite3_open_v2;
 
   late int Function(Pointer<Database> database) sqlite3_close_v2;
+  late Pointer<NativeFunction<sqlite3_close_v2_native_t>>
+      sqlite3_close_v2_native;
+  late Pointer<NativeFunction<Void Function(Pointer<Database> database)>>
+      sqlite3_close_v2_native_return_void;
 
   /// Compiling An SQL Statement
   ///
@@ -214,6 +218,10 @@
   /// statement after it has been finalized can result in undefined and
   /// undesirable behavior such as segfaults and heap corruption.
   late int Function(Pointer<Statement> statement) sqlite3_finalize;
+  late Pointer<NativeFunction<sqlite3_finalize_native_t>>
+      sqlite3_finalize_native;
+  late Pointer<NativeFunction<Void Function(Pointer<Statement> statement)>>
+      sqlite3_finalize_native_return_void;
 
   /// Number Of Columns In A Result Set
   ///
@@ -336,9 +344,10 @@
     sqlite3_open_v2 = sqlite
         .lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
         .asFunction();
-    sqlite3_close_v2 = sqlite
-        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
-        .asFunction();
+    sqlite3_close_v2_native = sqlite
+        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2");
+    sqlite3_close_v2_native_return_void = sqlite3_close_v2_native.cast();
+    sqlite3_close_v2 = sqlite3_close_v2_native.asFunction();
     sqlite3_prepare_v2 = sqlite
         .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
             "sqlite3_prepare_v2")
@@ -349,9 +358,10 @@
     sqlite3_reset = sqlite
         .lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
         .asFunction();
-    sqlite3_finalize = sqlite
-        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
-        .asFunction();
+    sqlite3_finalize_native = sqlite
+        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize");
+    sqlite3_finalize_native_return_void = sqlite3_finalize_native.cast();
+    sqlite3_finalize = sqlite3_finalize_native.asFunction();
     sqlite3_errstr = sqlite
         .lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
         .asFunction();
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index 9b0570c..fa6a8d5 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -21,19 +21,19 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  late Pointer<types.Database> _database;
+  late DatabaseResource _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
   Database(String path,
       [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
     Pointer<Pointer<types.Database>> dbOut = calloc();
-    final pathC = path.toNativeUtf8();
+    final pathC = Utf8Resource(path.toNativeUtf8());
     final int resultCode =
-        bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
-    _database = dbOut.value;
+        bindings.sqlite3_open_v2(pathC.unsafe(), dbOut, flags, nullptr);
+    _database = DatabaseResource(dbOut.value);
     calloc.free(dbOut);
-    calloc.free(pathC);
+    pathC.free();
 
     if (resultCode == Errors.SQLITE_OK) {
       _open = true;
@@ -53,7 +53,7 @@
   /// avoid resource leaks.
   void close() {
     assert(_open);
-    final int resultCode = bindings.sqlite3_close_v2(_database);
+    final int resultCode = _database.close();
     if (resultCode == Errors.SQLITE_OK) {
       _open = false;
     } else {
@@ -63,18 +63,17 @@
 
   /// Execute a query, discarding any returned rows.
   void execute(String query) {
-    Pointer<Pointer<Statement>> statementOut = calloc();
-    Pointer<Utf8> queryC = query.toNativeUtf8();
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = malloc();
+    final queryC = Utf8Resource(query.toNativeUtf8());
+    int resultCode = _database.prepare(queryC, -1, statementOut, nullptr);
+    final statement = StatementResource(statementOut.value);
     calloc.free(statementOut);
-    calloc.free(queryC);
+    queryC.free();
 
     while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
-      resultCode = bindings.sqlite3_step(statement);
+      resultCode = statement.step();
     }
-    bindings.sqlite3_finalize(statement);
+    statement.finalize();
     if (resultCode != Errors.SQLITE_DONE) {
       throw _loadError(resultCode);
     }
@@ -82,32 +81,33 @@
 
   /// Evaluate a query and return the resulting rows as an iterable.
   Result query(String query) {
-    Pointer<Pointer<Statement>> statementOut = calloc();
-    Pointer<Utf8> queryC = query.toNativeUtf8();
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = malloc();
+    final queryC = Utf8Resource(query.toNativeUtf8());
+    int resultCode = _database.prepare(queryC, -1, statementOut, nullptr);
+    final statement = StatementResource(statementOut.value);
     calloc.free(statementOut);
-    calloc.free(queryC);
+    queryC.free();
 
     if (resultCode != Errors.SQLITE_OK) {
-      bindings.sqlite3_finalize(statement);
+      statement.finalize();
       throw _loadError(resultCode);
     }
 
     Map<String, int> columnIndices = {};
-    int columnCount = bindings.sqlite3_column_count(statement);
+    int columnCount = statement.columnCount;
     for (int i = 0; i < columnCount; i++) {
-      String columnName =
-          bindings.sqlite3_column_name(statement, i).toDartString();
+      String columnName = statement.columnName(i);
       columnIndices[columnName] = i;
     }
 
     return Result._(this, statement, columnIndices);
   }
 
-  SQLiteException _loadError(int errorCode) {
-    String errorMessage = bindings.sqlite3_errmsg(_database).toDartString();
+  SQLiteException _loadError([int? errorCode]) {
+    String errorMessage = _database.errmsg().toDartString();
+    if (errorCode == null) {
+      return SQLiteException(errorMessage);
+    }
     String errorCodeExplanation =
         bindings.sqlite3_errstr(errorCode).toDartString();
     return SQLiteException(
@@ -125,7 +125,7 @@
 
   Result._(
     Database database,
-    Pointer<Statement> statement,
+    StatementResource statement,
     Map<String, int> columnIndices,
   ) : _iterator = _ResultIterator(statement, columnIndices) {}
 
@@ -135,7 +135,7 @@
 }
 
 class _ResultIterator implements ClosableIterator<Row> {
-  final Pointer<Statement> _statement;
+  final StatementResource _statement;
   final Map<String, int> _columnIndices;
 
   Row? _currentRow;
@@ -148,7 +148,7 @@
       throw SQLiteException("The result has already been closed.");
     }
     _currentRow?._setNotCurrent();
-    int stepResult = bindings.sqlite3_step(_statement);
+    int stepResult = _statement.step();
     if (stepResult == Errors.SQLITE_ROW) {
       _currentRow = Row._(_statement, _columnIndices);
       return true;
@@ -168,12 +168,12 @@
   void close() {
     _currentRow?._setNotCurrent();
     _closed = true;
-    bindings.sqlite3_finalize(_statement);
+    _statement.finalize();
   }
 }
 
 class Row {
-  final Pointer<Statement> _statement;
+  final StatementResource _statement;
   final Map<String, int> _columnIndices;
 
   bool _isCurrentRow = true;
@@ -201,12 +201,10 @@
 
     Type dynamicType;
     if (convert == Convert.DynamicType) {
-      dynamicType =
-          _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
+      dynamicType = _typeFromCode(_statement.columnType(columnIndex));
     } else {
-      dynamicType = _typeFromText(bindings
-          .sqlite3_column_decltype(_statement, columnIndex)
-          .toDartString());
+      dynamicType =
+          _typeFromText(_statement.columnDecltype(columnIndex).toDartString());
     }
 
     switch (dynamicType) {
@@ -230,7 +228,7 @@
   /// integer.
   int readColumnByIndexAsInt(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_int(_statement, columnIndex);
+    return _statement.columnInt(columnIndex);
   }
 
   /// Reads column [columnName] and converts to [Type.Text] if not text.
@@ -241,7 +239,7 @@
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
   String readColumnByIndexAsText(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_text(_statement, columnIndex).toDartString();
+    return _statement.columnText(columnIndex).toDartString();
   }
 
   void _checkIsCurrentRow() {
@@ -257,6 +255,93 @@
   }
 }
 
+class DatabaseResource implements Finalizable {
+  static final NativeFinalizer _finalizer =
+      NativeFinalizer(bindings.sqlite3_close_v2_native_return_void.cast());
+
+  /// [_statement] must never escape [StatementResource], otherwise the
+  /// [_finalizer] will run prematurely.
+  Pointer<types.Database> _database;
+
+  DatabaseResource(this._database) {
+    _finalizer.attach(this, _database.cast(), detach: this);
+  }
+
+  int close() {
+    _finalizer.detach(this);
+    return bindings.sqlite3_close_v2(_database);
+  }
+
+  int prepare(Utf8Resource query, int nbytes,
+      Pointer<Pointer<Statement>> statementOut, Pointer<Pointer<Utf8>> tail) {
+    int result = bindings.sqlite3_prepare_v2(
+        _database, query.unsafe(), nbytes, statementOut, tail);
+    return result;
+  }
+
+  Pointer<Utf8> errmsg() => bindings.sqlite3_errmsg(_database);
+}
+
+class StatementResource implements Finalizable {
+  static final NativeFinalizer _finalizer =
+      NativeFinalizer(bindings.sqlite3_finalize_native_return_void.cast());
+
+  /// [_statement] must never escape [StatementResource], otherwise the
+  /// [_finalizer] will run prematurely.
+  final Pointer<Statement> _statement;
+
+  StatementResource(this._statement) {
+    _finalizer.attach(this, _statement.cast(), detach: this);
+  }
+
+  int finalize() {
+    _finalizer.detach(this);
+    return bindings.sqlite3_finalize(_statement);
+  }
+
+  int get columnCount => bindings.sqlite3_column_count(_statement);
+
+  String columnName(int index) =>
+      bindings.sqlite3_column_name(_statement, index).toDartString();
+
+  int step() => bindings.sqlite3_step(_statement);
+
+  int columnType(int columnIndex) =>
+      bindings.sqlite3_column_type(_statement, columnIndex);
+
+  Pointer<Utf8> columnDecltype(int columnIndex) =>
+      bindings.sqlite3_column_decltype(_statement, columnIndex);
+
+  int columnInt(int columnIndex) =>
+      bindings.sqlite3_column_int(_statement, columnIndex);
+
+  Pointer<Utf8> columnText(int columnIndex) =>
+      bindings.sqlite3_column_text(_statement, columnIndex);
+}
+
+class Utf8Resource implements Finalizable {
+  static final NativeFinalizer _finalizer = NativeFinalizer(posixFree);
+
+  /// [_cString] must never escape [Utf8Resource], otherwise the
+  /// [_finalizer] will run prematurely.
+  final Pointer<Utf8> _cString;
+
+  Utf8Resource(this._cString) {
+    _finalizer.attach(this, _cString.cast(), detach: this);
+  }
+
+  void free() {
+    _finalizer.detach(this);
+    calloc.free(_cString);
+  }
+
+  /// Ensure this [Utf8Resource] stays in scope longer than the inner resource.
+  Pointer<Utf8> unsafe() => _cString;
+}
+
+final DynamicLibrary stdlib = DynamicLibrary.process();
+final posixFree = stdlib.lookup<NativeFunction<Void Function(Pointer)>>("free");
+
 Type _typeFromCode(int code) {
   switch (code) {
     case Types.SQLITE_INTEGER:
diff --git a/samples/ffi/sqlite/pubspec.yaml b/samples/ffi/sqlite/pubspec.yaml
index 90e67f4..ab886aa 100644
--- a/samples/ffi/sqlite/pubspec.yaml
+++ b/samples/ffi/sqlite/pubspec.yaml
@@ -2,10 +2,9 @@
 version: 0.0.1
 description: >-
   Sqlite3 wrapper. Demo for dart:ffi.
-author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
 environment:
-  sdk: '>=2.12.0-0 <3.0.0'
+  sdk: '>=2.17.0 <3.0.0'
 dependencies:
-  ffi: ^1.1.2
+  ffi: ^2.0.0
 dev_dependencies:
-  test: ^1.16.0-nullsafety.12
+  test: ^1.21.1
diff --git a/samples_2/ffi/sqlite/README.md b/samples_2/ffi/sqlite/README.md
index fbd5cb9..c4656df 100644
--- a/samples_2/ffi/sqlite/README.md
+++ b/samples_2/ffi/sqlite/README.md
@@ -20,25 +20,10 @@
 ## Building and Running this Sample
 
 Building and running this sample is done through pub.
-Running `pub get` and `pub run example/main` should produce the following output.
+Running `dart run example/main` should produce the following output.
 
 ```sh
-$ pub get
-Resolving dependencies... (6.8s)
-+ analyzer 0.35.4
-...
-+ yaml 2.1.15
-Downloading analyzer 0.35.4...
-Downloading kernel 0.3.14...
-Downloading front_end 0.1.14...
-Changed 47 dependencies!
-Precompiling executables... (18.0s)
-Precompiled test:test.
-
-```
-
-```
-$ pub run example/main
+$ dart run example/main
 1 Chocolade chip cookie Chocolade cookie foo
 2 Ginger cookie null 42
 3 Cinnamon roll null null
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart b/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart
index a1cdba7..2491813 100644
--- a/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart
+++ b/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -33,6 +33,9 @@
       int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
 
   int Function(Pointer<Database> database) sqlite3_close_v2;
+  Pointer<NativeFunction<sqlite3_close_v2_native_t>> sqlite3_close_v2_native;
+  Pointer<NativeFunction<Void Function(Pointer<Database> database)>>
+      sqlite3_close_v2_native_return_void;
 
   /// Compiling An SQL Statement
   ///
@@ -213,6 +216,9 @@
   /// statement after it has been finalized can result in undefined and
   /// undesirable behavior such as segfaults and heap corruption.
   int Function(Pointer<Statement> statement) sqlite3_finalize;
+  Pointer<NativeFunction<sqlite3_finalize_native_t>> sqlite3_finalize_native;
+  Pointer<NativeFunction<Void Function(Pointer<Statement> statement)>>
+      sqlite3_finalize_native_return_void;
 
   /// Number Of Columns In A Result Set
   ///
@@ -335,9 +341,10 @@
     sqlite3_open_v2 = sqlite
         .lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
         .asFunction();
-    sqlite3_close_v2 = sqlite
-        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
-        .asFunction();
+    sqlite3_close_v2_native = sqlite
+        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2");
+    sqlite3_close_v2_native_return_void = sqlite3_close_v2_native.cast();
+    sqlite3_close_v2 = sqlite3_close_v2_native.asFunction();
     sqlite3_prepare_v2 = sqlite
         .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
             "sqlite3_prepare_v2")
@@ -348,9 +355,10 @@
     sqlite3_reset = sqlite
         .lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
         .asFunction();
-    sqlite3_finalize = sqlite
-        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
-        .asFunction();
+    sqlite3_finalize_native = sqlite
+        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize");
+    sqlite3_finalize_native_return_void = sqlite3_finalize_native.cast();
+    sqlite3_finalize = sqlite3_finalize_native.asFunction();
     sqlite3_errstr = sqlite
         .lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
         .asFunction();
diff --git a/samples_2/ffi/sqlite/lib/src/database.dart b/samples_2/ffi/sqlite/lib/src/database.dart
index d65724f..5bfc770 100644
--- a/samples_2/ffi/sqlite/lib/src/database.dart
+++ b/samples_2/ffi/sqlite/lib/src/database.dart
@@ -23,19 +23,19 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  Pointer<types.Database> _database;
+  DatabaseResource _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
   Database(String path,
       [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
     Pointer<Pointer<types.Database>> dbOut = calloc();
-    final pathC = path.toNativeUtf8();
+    final pathC = Utf8Resource(path.toNativeUtf8());
     final int resultCode =
-        bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
-    _database = dbOut.value;
+        bindings.sqlite3_open_v2(pathC.unsafe(), dbOut, flags, nullptr);
+    _database = DatabaseResource(dbOut.value);
     calloc.free(dbOut);
-    calloc.free(pathC);
+    pathC.free();
 
     if (resultCode == Errors.SQLITE_OK) {
       _open = true;
@@ -55,7 +55,7 @@
   /// avoid resource leaks.
   void close() {
     assert(_open);
-    final int resultCode = bindings.sqlite3_close_v2(_database);
+    final int resultCode = _database.close();
     if (resultCode == Errors.SQLITE_OK) {
       _open = false;
     } else {
@@ -65,18 +65,17 @@
 
   /// Execute a query, discarding any returned rows.
   void execute(String query) {
-    Pointer<Pointer<Statement>> statementOut = calloc();
-    Pointer<Utf8> queryC = query.toNativeUtf8();
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = malloc();
+    final queryC = Utf8Resource(query.toNativeUtf8());
+    int resultCode = _database.prepare(queryC, -1, statementOut, nullptr);
+    final statement = StatementResource(statementOut.value);
     calloc.free(statementOut);
-    calloc.free(queryC);
+    queryC.free();
 
     while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
-      resultCode = bindings.sqlite3_step(statement);
+      resultCode = statement.step();
     }
-    bindings.sqlite3_finalize(statement);
+    statement.finalize();
     if (resultCode != Errors.SQLITE_DONE) {
       throw _loadError(resultCode);
     }
@@ -84,24 +83,22 @@
 
   /// Evaluate a query and return the resulting rows as an iterable.
   Result query(String query) {
-    Pointer<Pointer<Statement>> statementOut = calloc();
-    Pointer<Utf8> queryC = query.toNativeUtf8();
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = malloc();
+    final queryC = Utf8Resource(query.toNativeUtf8());
+    int resultCode = _database.prepare(queryC, -1, statementOut, nullptr);
+    final statement = StatementResource(statementOut.value);
     calloc.free(statementOut);
-    calloc.free(queryC);
+    queryC.free();
 
     if (resultCode != Errors.SQLITE_OK) {
-      bindings.sqlite3_finalize(statement);
+      statement.finalize();
       throw _loadError(resultCode);
     }
 
     Map<String, int> columnIndices = {};
-    int columnCount = bindings.sqlite3_column_count(statement);
+    int columnCount = statement.columnCount;
     for (int i = 0; i < columnCount; i++) {
-      String columnName =
-          bindings.sqlite3_column_name(statement, i).toDartString();
+      String columnName = statement.columnName(i);
       columnIndices[columnName] = i;
     }
 
@@ -109,7 +106,7 @@
   }
 
   SQLiteException _loadError([int errorCode]) {
-    String errorMessage = bindings.sqlite3_errmsg(_database).toDartString();
+    String errorMessage = _database.errmsg().toDartString();
     if (errorCode == null) {
       return SQLiteException(errorMessage);
     }
@@ -126,18 +123,13 @@
 /// Please note that this iterator should be [close]d manually if not all [Row]s
 /// are consumed.
 class Result extends IterableBase<Row> implements ClosableIterable<Row> {
-  final Database _database;
   final ClosableIterator<Row> _iterator;
-  final Pointer<Statement> _statement;
-  final Map<String, int> _columnIndices;
-
-  Row _currentRow = null;
 
   Result._(
-    this._database,
-    this._statement,
-    this._columnIndices,
-  ) : _iterator = _ResultIterator(_statement, _columnIndices) {}
+    Database database,
+    StatementResource statement,
+    Map<String, int> columnIndices,
+  ) : _iterator = _ResultIterator(statement, columnIndices) {}
 
   void close() => _iterator.close();
 
@@ -145,10 +137,10 @@
 }
 
 class _ResultIterator implements ClosableIterator<Row> {
-  final Pointer<Statement> _statement;
+  final StatementResource _statement;
   final Map<String, int> _columnIndices;
 
-  Row _currentRow = null;
+  Row _currentRow;
   bool _closed = false;
 
   _ResultIterator(this._statement, this._columnIndices) {}
@@ -157,8 +149,10 @@
     if (_closed) {
       throw SQLiteException("The result has already been closed.");
     }
-    _currentRow?._setNotCurrent();
-    int stepResult = bindings.sqlite3_step(_statement);
+    if (_currentRow != null) {
+      _currentRow._setNotCurrent();
+    }
+    int stepResult = _statement.step();
     if (stepResult == Errors.SQLITE_ROW) {
       _currentRow = Row._(_statement, _columnIndices);
       return true;
@@ -176,14 +170,14 @@
   }
 
   void close() {
-    _currentRow?._setNotCurrent();
+    _currentRow._setNotCurrent();
     _closed = true;
-    bindings.sqlite3_finalize(_statement);
+    _statement.finalize();
   }
 }
 
 class Row {
-  final Pointer<Statement> _statement;
+  final StatementResource _statement;
   final Map<String, int> _columnIndices;
 
   bool _isCurrentRow = true;
@@ -211,12 +205,10 @@
 
     Type dynamicType;
     if (convert == Convert.DynamicType) {
-      dynamicType =
-          _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
+      dynamicType = _typeFromCode(_statement.columnType(columnIndex));
     } else {
-      dynamicType = _typeFromText(bindings
-          .sqlite3_column_decltype(_statement, columnIndex)
-          .toDartString());
+      dynamicType =
+          _typeFromText(_statement.columnDecltype(columnIndex).toDartString());
     }
 
     switch (dynamicType) {
@@ -226,7 +218,6 @@
         return readColumnByIndexAsText(columnIndex);
       case Type.Null:
         return null;
-        break;
       default:
     }
   }
@@ -241,7 +232,7 @@
   /// integer.
   int readColumnByIndexAsInt(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_int(_statement, columnIndex);
+    return _statement.columnInt(columnIndex);
   }
 
   /// Reads column [columnName] and converts to [Type.Text] if not text.
@@ -252,7 +243,7 @@
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
   String readColumnByIndexAsText(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_text(_statement, columnIndex).toDartString();
+    return _statement.columnText(columnIndex).toDartString();
   }
 
   void _checkIsCurrentRow() {
@@ -268,6 +259,93 @@
   }
 }
 
+class DatabaseResource implements Finalizable {
+  static final NativeFinalizer _finalizer =
+      NativeFinalizer(bindings.sqlite3_close_v2_native_return_void.cast());
+
+  /// [_statement] must never escape [StatementResource], otherwise the
+  /// [_finalizer] will run prematurely.
+  Pointer<types.Database> _database;
+
+  DatabaseResource(this._database) {
+    _finalizer.attach(this, _database.cast(), detach: this);
+  }
+
+  int close() {
+    _finalizer.detach(this);
+    return bindings.sqlite3_close_v2(_database);
+  }
+
+  int prepare(Utf8Resource query, int nbytes,
+      Pointer<Pointer<Statement>> statementOut, Pointer<Pointer<Utf8>> tail) {
+    int result = bindings.sqlite3_prepare_v2(
+        _database, query.unsafe(), nbytes, statementOut, tail);
+    return result;
+  }
+
+  Pointer<Utf8> errmsg() => bindings.sqlite3_errmsg(_database);
+}
+
+class StatementResource implements Finalizable {
+  static final NativeFinalizer _finalizer =
+      NativeFinalizer(bindings.sqlite3_finalize_native_return_void.cast());
+
+  /// [_statement] must never escape [StatementResource], otherwise the
+  /// [_finalizer] will run prematurely.
+  final Pointer<Statement> _statement;
+
+  StatementResource(this._statement) {
+    _finalizer.attach(this, _statement.cast(), detach: this);
+  }
+
+  int finalize() {
+    _finalizer.detach(this);
+    return bindings.sqlite3_finalize(_statement);
+  }
+
+  int get columnCount => bindings.sqlite3_column_count(_statement);
+
+  String columnName(int index) =>
+      bindings.sqlite3_column_name(_statement, index).toDartString();
+
+  int step() => bindings.sqlite3_step(_statement);
+
+  int columnType(int columnIndex) =>
+      bindings.sqlite3_column_type(_statement, columnIndex);
+
+  Pointer<Utf8> columnDecltype(int columnIndex) =>
+      bindings.sqlite3_column_decltype(_statement, columnIndex);
+
+  int columnInt(int columnIndex) =>
+      bindings.sqlite3_column_int(_statement, columnIndex);
+
+  Pointer<Utf8> columnText(int columnIndex) =>
+      bindings.sqlite3_column_text(_statement, columnIndex);
+}
+
+class Utf8Resource implements Finalizable {
+  static final NativeFinalizer _finalizer = NativeFinalizer(posixFree);
+
+  /// [_cString] must never escape [Utf8Resource], otherwise the
+  /// [_finalizer] will run prematurely.
+  final Pointer<Utf8> _cString;
+
+  Utf8Resource(this._cString) {
+    _finalizer.attach(this, _cString.cast(), detach: this);
+  }
+
+  void free() {
+    _finalizer.detach(this);
+    calloc.free(_cString);
+  }
+
+  /// Ensure this [Utf8Resource] stays in scope longer than the inner resource.
+  Pointer<Utf8> unsafe() => _cString;
+}
+
+final DynamicLibrary stdlib = DynamicLibrary.process();
+final posixFree = stdlib.lookup<NativeFunction<Void Function(Pointer)>>("free");
+
 Type _typeFromCode(int code) {
   switch (code) {
     case Types.SQLITE_INTEGER:
@@ -297,7 +375,6 @@
     case "null":
       return Type.Null;
   }
-  if (textRepresentation == null) return Type.Null;
   throw Exception("Unknown type [$textRepresentation]");
 }
 
diff --git a/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart b/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
index b783ad8..fccdca3 100644
--- a/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
+++ b/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
@@ -7,8 +7,7 @@
 import 'dart:ffi';
 import 'dart:io' show Platform;
 
-String _platformPath(String name, {String path}) {
-  if (path == null) path = "";
+String _platformPath(String name, String path) {
   if (Platform.isLinux || Platform.isAndroid || Platform.isFuchsia)
     return path + "lib" + name + ".so";
   if (Platform.isMacOS) return path + "lib" + name + ".dylib";
@@ -16,7 +15,7 @@
   throw Exception("Platform not implemented");
 }
 
-DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
-  String fullPath = _platformPath(name, path: path);
+DynamicLibrary dlopenPlatformSpecific(String name, {String path = ""}) {
+  String fullPath = _platformPath(name, path);
   return DynamicLibrary.open(fullPath);
 }
diff --git a/samples_2/ffi/sqlite/pubspec.yaml b/samples_2/ffi/sqlite/pubspec.yaml
index 762107f..ab886aa 100644
--- a/samples_2/ffi/sqlite/pubspec.yaml
+++ b/samples_2/ffi/sqlite/pubspec.yaml
@@ -2,10 +2,9 @@
 version: 0.0.1
 description: >-
   Sqlite3 wrapper. Demo for dart:ffi.
-author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.17.0 <3.0.0'
 dependencies:
-  ffi: ^1.1.2
+  ffi: ^2.0.0
 dev_dependencies:
-  test: ^1.5.3
+  test: ^1.21.1
diff --git a/samples_2/ffi/sqlite/test/sqlite_test.dart b/samples_2/ffi/sqlite/test/sqlite_test.dart
index 91efe13..8640438 100644
--- a/samples_2/ffi/sqlite/test/sqlite_test.dart
+++ b/samples_2/ffi/sqlite/test/sqlite_test.dart
@@ -49,8 +49,7 @@
       expect(true, 1 <= id && id <= 3);
       String name = r.readColumnByIndex(1);
       expect(true, name is String);
-      String alternativeName = r.readColumn("alternative_name");
-      expect(true, alternativeName is String || alternativeName == null);
+      final alternativeName = r.readColumn("alternative_name") as String;
       dynamic multiTypedValue = r.readColumn("multi_typed_column");
       expect(
           true,
@@ -76,8 +75,7 @@
       expect(true, 1 <= id && id <= 3);
       String name = r.readColumnByIndex(1);
       expect(true, name is String);
-      String alternativeName = r.readColumn("alternative_name");
-      expect(true, alternativeName is String || alternativeName == null);
+      final alternativeName = r.readColumn("alternative_name") as String;
       dynamic multiTypedValue = r.readColumn("multi_typed_column");
       expect(
           true,
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index 6ea7e64..e10c97c 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -384,110 +384,10 @@
   static const warningHeader = "warning";
   static const wwwAuthenticateHeader = "www-authenticate";
 
-  @Deprecated("Use acceptHeader instead")
-  static const ACCEPT = acceptHeader;
-  @Deprecated("Use acceptCharsetHeader instead")
-  static const ACCEPT_CHARSET = acceptCharsetHeader;
-  @Deprecated("Use acceptEncodingHeader instead")
-  static const ACCEPT_ENCODING = acceptEncodingHeader;
-  @Deprecated("Use acceptLanguageHeader instead")
-  static const ACCEPT_LANGUAGE = acceptLanguageHeader;
-  @Deprecated("Use acceptRangesHeader instead")
-  static const ACCEPT_RANGES = acceptRangesHeader;
-  @Deprecated("Use ageHeader instead")
-  static const AGE = ageHeader;
-  @Deprecated("Use allowHeader instead")
-  static const ALLOW = allowHeader;
-  @Deprecated("Use authorizationHeader instead")
-  static const AUTHORIZATION = authorizationHeader;
-  @Deprecated("Use cacheControlHeader instead")
-  static const CACHE_CONTROL = cacheControlHeader;
-  @Deprecated("Use connectionHeader instead")
-  static const CONNECTION = connectionHeader;
-  @Deprecated("Use contentEncodingHeader instead")
-  static const CONTENT_ENCODING = contentEncodingHeader;
-  @Deprecated("Use contentLanguageHeader instead")
-  static const CONTENT_LANGUAGE = contentLanguageHeader;
-  @Deprecated("Use contentLengthHeader instead")
-  static const CONTENT_LENGTH = contentLengthHeader;
-  @Deprecated("Use contentLocationHeader instead")
-  static const CONTENT_LOCATION = contentLocationHeader;
-  @Deprecated("Use contentMD5Header instead")
-  static const CONTENT_MD5 = contentMD5Header;
-  @Deprecated("Use contentRangeHeader instead")
-  static const CONTENT_RANGE = contentRangeHeader;
-  @Deprecated("Use contentTypeHeader instead")
-  static const CONTENT_TYPE = contentTypeHeader;
-  @Deprecated("Use dateHeader instead")
-  static const DATE = dateHeader;
-  @Deprecated("Use etagHeader instead")
-  static const ETAG = etagHeader;
-  @Deprecated("Use expectHeader instead")
-  static const EXPECT = expectHeader;
-  @Deprecated("Use expiresHeader instead")
-  static const EXPIRES = expiresHeader;
-  @Deprecated("Use fromHeader instead")
-  static const FROM = fromHeader;
-  @Deprecated("Use hostHeader instead")
-  static const HOST = hostHeader;
-  @Deprecated("Use ifMatchHeader instead")
-  static const IF_MATCH = ifMatchHeader;
-  @Deprecated("Use ifModifiedSinceHeader instead")
-  static const IF_MODIFIED_SINCE = ifModifiedSinceHeader;
-  @Deprecated("Use ifNoneMatchHeader instead")
-  static const IF_NONE_MATCH = ifNoneMatchHeader;
-  @Deprecated("Use ifRangeHeader instead")
-  static const IF_RANGE = ifRangeHeader;
-  @Deprecated("Use ifUnmodifiedSinceHeader instead")
-  static const IF_UNMODIFIED_SINCE = ifUnmodifiedSinceHeader;
-  @Deprecated("Use lastModifiedHeader instead")
-  static const LAST_MODIFIED = lastModifiedHeader;
-  @Deprecated("Use locationHeader instead")
-  static const LOCATION = locationHeader;
-  @Deprecated("Use maxForwardsHeader instead")
-  static const MAX_FORWARDS = maxForwardsHeader;
-  @Deprecated("Use pragmaHeader instead")
-  static const PRAGMA = pragmaHeader;
-  @Deprecated("Use proxyAuthenticateHeader instead")
-  static const PROXY_AUTHENTICATE = proxyAuthenticateHeader;
-  @Deprecated("Use proxyAuthorizationHeader instead")
-  static const PROXY_AUTHORIZATION = proxyAuthorizationHeader;
-  @Deprecated("Use rangeHeader instead")
-  static const RANGE = rangeHeader;
-  @Deprecated("Use refererHeader instead")
-  static const REFERER = refererHeader;
-  @Deprecated("Use retryAfterHeader instead")
-  static const RETRY_AFTER = retryAfterHeader;
-  @Deprecated("Use serverHeader instead")
-  static const SERVER = serverHeader;
-  @Deprecated("Use teHeader instead")
-  static const TE = teHeader;
-  @Deprecated("Use trailerHeader instead")
-  static const TRAILER = trailerHeader;
-  @Deprecated("Use transferEncodingHeader instead")
-  static const TRANSFER_ENCODING = transferEncodingHeader;
-  @Deprecated("Use upgradeHeader instead")
-  static const UPGRADE = upgradeHeader;
-  @Deprecated("Use userAgentHeader instead")
-  static const USER_AGENT = userAgentHeader;
-  @Deprecated("Use varyHeader instead")
-  static const VARY = varyHeader;
-  @Deprecated("Use viaHeader instead")
-  static const VIA = viaHeader;
-  @Deprecated("Use warningHeader instead")
-  static const WARNING = warningHeader;
-  @Deprecated("Use wwwAuthenticateHeader instead")
-  static const WWW_AUTHENTICATE = wwwAuthenticateHeader;
-
   // Cookie headers from RFC 6265.
   static const cookieHeader = "cookie";
   static const setCookieHeader = "set-cookie";
 
-  @Deprecated("Use cookieHeader instead")
-  static const COOKIE = cookieHeader;
-  @Deprecated("Use setCookieHeader instead")
-  static const SET_COOKIE = setCookieHeader;
-
   // TODO(39783): Document this.
   static const generalHeaders = [
     cacheControlHeader,
@@ -501,9 +401,6 @@
     warningHeader
   ];
 
-  @Deprecated("Use generalHeaders instead")
-  static const GENERAL_HEADERS = generalHeaders;
-
   static const entityHeaders = [
     allowHeader,
     contentEncodingHeader,
@@ -517,9 +414,6 @@
     lastModifiedHeader
   ];
 
-  @Deprecated("Use entityHeaders instead")
-  static const ENTITY_HEADERS = entityHeaders;
-
   static const responseHeaders = [
     acceptRangesHeader,
     ageHeader,
@@ -532,9 +426,6 @@
     wwwAuthenticateHeader
   ];
 
-  @Deprecated("Use responseHeaders instead")
-  static const RESPONSE_HEADERS = responseHeaders;
-
   static const requestHeaders = [
     acceptHeader,
     acceptCharsetHeader,
@@ -557,9 +448,6 @@
     userAgentHeader
   ];
 
-  @Deprecated("Use requestHeaders instead")
-  static const REQUEST_HEADERS = requestHeaders;
-
   /// The date specified by the [dateHeader] header, if any.
   DateTime? date;
 
@@ -773,29 +661,21 @@
   ///
   ///     text/plain; charset=utf-8
   static final text = ContentType("text", "plain", charset: "utf-8");
-  @Deprecated("Use text instead")
-  static final TEXT = text;
 
   /// Content type for HTML using UTF-8 encoding.
   ///
   ///    text/html; charset=utf-8
   static final html = ContentType("text", "html", charset: "utf-8");
-  @Deprecated("Use html instead")
-  static final HTML = html;
 
   /// Content type for JSON using UTF-8 encoding.
   ///
   ///    application/json; charset=utf-8
   static final json = ContentType("application", "json", charset: "utf-8");
-  @Deprecated("Use json instead")
-  static final JSON = json;
 
   /// Content type for binary data.
   ///
   ///    application/octet-stream
   static final binary = ContentType("application", "octet-stream");
-  @Deprecated("Use binary instead")
-  static final BINARY = binary;
 
   /// Creates a new content type object setting the primary type and
   /// sub type. The charset and additional parameters can also be set
@@ -1262,12 +1142,8 @@
 ///     client.findProxy = null;
 abstract class HttpClient {
   static const int defaultHttpPort = 80;
-  @Deprecated("Use defaultHttpPort instead")
-  static const int DEFAULT_HTTP_PORT = defaultHttpPort;
 
   static const int defaultHttpsPort = 443;
-  @Deprecated("Use defaultHttpsPort instead")
-  static const int DEFAULT_HTTPS_PORT = defaultHttpsPort;
 
   /// Enable logging of HTTP requests from all [HttpClient]s to the developer
   /// timeline.
diff --git a/sdk/lib/_http/websocket.dart b/sdk/lib/_http/websocket.dart
index 9503ae3..a01823c 100644
--- a/sdk/lib/_http/websocket.dart
+++ b/sdk/lib/_http/websocket.dart
@@ -19,33 +19,6 @@
   static const int missingMandatoryExtension = 1010;
   static const int internalServerError = 1011;
   static const int reserved1015 = 1015;
-
-  @Deprecated("Use normalClosure instead")
-  static const int NORMAL_CLOSURE = normalClosure;
-  @Deprecated("Use goingAway instead")
-  static const int GOING_AWAY = goingAway;
-  @Deprecated("Use protocolError instead")
-  static const int PROTOCOL_ERROR = protocolError;
-  @Deprecated("Use unsupportedData instead")
-  static const int UNSUPPORTED_DATA = unsupportedData;
-  @Deprecated("Use reserved1004 instead")
-  static const int RESERVED_1004 = reserved1004;
-  @Deprecated("Use noStatusReceived instead")
-  static const int NO_STATUS_RECEIVED = noStatusReceived;
-  @Deprecated("Use abnormalClosure instead")
-  static const int ABNORMAL_CLOSURE = abnormalClosure;
-  @Deprecated("Use invalidFramePayloadData instead")
-  static const int INVALID_FRAME_PAYLOAD_DATA = invalidFramePayloadData;
-  @Deprecated("Use policyViolation instead")
-  static const int POLICY_VIOLATION = policyViolation;
-  @Deprecated("Use messageTooBig instead")
-  static const int MESSAGE_TOO_BIG = messageTooBig;
-  @Deprecated("Use missingMandatoryExtension instead")
-  static const int MISSING_MANDATORY_EXTENSION = missingMandatoryExtension;
-  @Deprecated("Use internalServerError instead")
-  static const int INTERNAL_SERVER_ERROR = internalServerError;
-  @Deprecated("Use reserved1015 instead")
-  static const int RESERVED_1015 = reserved1015;
 }
 
 /// Options controlling compression in a [WebSocket].
@@ -68,8 +41,6 @@
   /// * `clientMaxWindowBits`: null (default maximal window size of 15 bits)
   /// * `serverMaxWindowBits`: null (default maximal window size of 15 bits)
   static const CompressionOptions compressionDefault = CompressionOptions();
-  @Deprecated("Use compressionDefault instead")
-  static const CompressionOptions DEFAULT = compressionDefault;
 
   /// No-compression configuration.
   ///
@@ -77,8 +48,6 @@
   /// [WebSocket].
   static const CompressionOptions compressionOff =
       CompressionOptions(enabled: false);
-  @Deprecated("Use compressionOff instead")
-  static const CompressionOptions OFF = compressionOff;
 
   /// Whether the client will reuse its compression instances.
   final bool clientNoContextTakeover;
@@ -300,15 +269,6 @@
   static const int closing = 2;
   static const int closed = 3;
 
-  @Deprecated("Use connecting instead")
-  static const int CONNECTING = connecting;
-  @Deprecated("Use open instead")
-  static const int OPEN = open;
-  @Deprecated("Use closing instead")
-  static const int CLOSING = closing;
-  @Deprecated("Use closed instead")
-  static const int CLOSED = closed;
-
   /// The interval between ping signals.
   ///
   /// A ping message is sent every [pingInterval], starting at the first
diff --git a/sdk/lib/_internal/wasm/lib/js_helper.dart b/sdk/lib/_internal/wasm/lib/js_helper.dart
new file mode 100644
index 0000000..fc392e7
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/js_helper.dart
@@ -0,0 +1,120 @@
+// 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.
+
+// Helpers for working with JS.
+library dart.js_helper;
+
+import 'dart:_internal';
+import 'dart:wasm';
+
+/// [JSValue] is the root of the JS interop object hierarchy.
+class JSValue {
+  final WasmAnyRef _ref;
+
+  JSValue(this._ref);
+
+  static JSValue? box(WasmAnyRef? ref) => ref == null ? null : JSValue(ref);
+
+  WasmAnyRef toAnyRef() => _ref;
+  String toString() => jsStringToDartString(_ref);
+  List<Object?> toObjectList() => jsArrayToDartList(_ref);
+  Object toObject() => jsObjectToDartObject(_ref);
+}
+
+extension StringToJS on String {
+  JSValue toJS() => JSValue(jsStringFromDartString(this));
+}
+
+extension ListOfObjectToJS on List<Object?> {
+  JSValue toJS() => JSValue(jsArrayFromDartList(this));
+}
+
+extension ObjectToJS on Object {
+  JSValue toJS() => JSValue(jsObjectFromDartObject(this));
+}
+
+Object? toDart(WasmAnyRef? ref) {
+  if (ref == null) {
+    return null;
+  }
+  return jsObjectToDartObject(dartifyRaw(ref)!);
+}
+
+Object jsObjectToDartObject(WasmAnyRef ref) => unsafeCastOpaque<Object>(ref);
+
+WasmAnyRef jsObjectFromDartObject(Object object) =>
+    unsafeCastOpaque<WasmAnyRef>(object);
+
+@pragma("wasm:import", "dart2wasm.arrayFromDartList")
+external WasmAnyRef jsArrayFromDartList(List<Object?> list);
+
+@pragma("wasm:import", "dart2wasm.arrayToDartList")
+external List<Object?> jsArrayToDartList(WasmAnyRef list);
+
+@pragma("wasm:import", "dart2wasm.stringFromDartString")
+external WasmAnyRef jsStringFromDartString(String string);
+
+@pragma("wasm:import", "dart2wasm.stringToDartString")
+external String jsStringToDartString(WasmAnyRef string);
+
+@pragma("wasm:import", "dart2wasm.eval")
+external void evalRaw(WasmAnyRef code);
+
+@pragma("wasm:import", "dart2wasm.dartify")
+external WasmAnyRef? dartifyRaw(WasmAnyRef? object);
+
+@pragma("wasm:import", "dart2wasm.newObject")
+external WasmAnyRef newObjectRaw();
+
+@pragma("wasm:import", "dart2wasm.globalThis")
+external WasmAnyRef globalThisRaw();
+
+@pragma("wasm:import", "dart2wasm.callConstructorVarArgs")
+external WasmAnyRef callConstructorVarArgsRaw(WasmAnyRef o, WasmAnyRef args);
+
+@pragma("wasm:import", "dart2wasm.hasProperty")
+external bool hasPropertyRaw(WasmAnyRef o, WasmAnyRef name);
+
+@pragma("wasm:import", "dart2wasm.getProperty")
+external WasmAnyRef? getPropertyRaw(WasmAnyRef o, WasmAnyRef name);
+
+@pragma("wasm:import", "dart2wasm.setProperty")
+external WasmAnyRef? setPropertyRaw(
+    WasmAnyRef o, WasmAnyRef name, WasmAnyRef? value);
+
+@pragma("wasm:import", "dart2wasm.callMethodVarArgs")
+external WasmAnyRef? callMethodVarArgsRaw(
+    WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
+
+WasmAnyRef? jsifyRaw(Object? object) {
+  if (object == null) {
+    return null;
+  } else if (object is JSValue) {
+    return object.toAnyRef();
+  } else if (object is String) {
+    return jsStringFromDartString(object);
+  } else if (object is List<Object?>) {
+    return jsArrayFromDartList(object);
+  } else {
+    return jsObjectFromDartObject(object);
+  }
+}
+
+/// js_util_wasm methods used by the wasm runtime.
+@pragma("wasm:export", "\$listLength")
+double _listLength(List list) => list.length.toDouble();
+
+@pragma("wasm:export", "\$listRead")
+WasmAnyRef? _listRead(List<Object?> list, double index) =>
+    jsifyRaw(list[index.toInt()]);
+
+@pragma("wasm:export", "\$listAllocate")
+List<Object?> _listAllocate() => [];
+
+@pragma("wasm:export", "\$listAdd")
+void _listAdd(List<Object?> list, WasmAnyRef? item) =>
+    list.add(dartifyRaw(item));
+
+@pragma("wasm:export", "\$boxJSValue")
+JSValue _boxJSValue(WasmAnyRef ref) => JSValue(ref);
diff --git a/sdk/lib/_internal/wasm/lib/js_util_patch.dart b/sdk/lib/_internal/wasm/lib/js_util_patch.dart
new file mode 100644
index 0000000..cbce99d
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/js_util_patch.dart
@@ -0,0 +1,106 @@
+// 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.
+
+library dart.js_util;
+
+import "dart:_internal";
+import "dart:_js_helper";
+
+@patch
+dynamic jsify(Object? object) => JSValue.box(jsifyRaw(object));
+
+@patch
+Object get globalThis => JSValue(globalThisRaw());
+
+@patch
+T newObject<T>() => JSValue(newObjectRaw()) as T;
+
+@patch
+bool hasProperty(Object o, String name) =>
+    hasPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef());
+
+@patch
+T getProperty<T>(Object o, String name) =>
+    toDart(getPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef())) as T;
+
+@patch
+T setProperty<T>(Object o, String name, T? value) => toDart(
+    setPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef(), jsifyRaw(value))) as T;
+
+@patch
+T callMethod<T>(Object o, String method, List<Object?> args) =>
+    toDart(callMethodVarArgsRaw(
+        jsifyRaw(o)!, method.toJS().toAnyRef(), args.toJS().toAnyRef())) as T;
+
+@patch
+bool instanceof(Object? o, Object type) => throw 'unimplemented';
+
+@patch
+T callConstructor<T>(Object o, List<Object?> args) =>
+    toDart(callConstructorVarArgsRaw(jsifyRaw(o)!, args.toJS().toAnyRef()))!
+        as T;
+
+@patch
+T add<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+T subtract<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+T multiply<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+T divide<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+T exponentiate<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+T modulo<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool equal<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool strictEqual<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool notEqual<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool strictNotEqual<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool greaterThan<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool greaterThanOrEqual<T>(Object? first, Object? second) =>
+    throw 'unimplemented';
+
+@patch
+bool lessThan<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+bool lessThanOrEqual<T>(Object? first, Object? second) => throw 'unimplemented';
+
+@patch
+Future<T> promiseToFuture<T>(Object jsPromise) => throw 'unimplemented';
+
+@patch
+Object? objectGetPrototypeOf(Object? object) => throw 'unimplemented';
+
+@patch
+Object? get objectPrototype => throw 'unimplemented';
+
+@patch
+List<Object?> objectKeys(Object? object) => throw 'unimplemented';
+
+@patch
+Object? dartify(Object? object) {
+  if (object is JSValue) {
+    return jsObjectToDartObject(dartifyRaw(object.toAnyRef())!);
+  } else {
+    return object;
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/js_util_wasm_patch.dart b/sdk/lib/_internal/wasm/lib/js_util_wasm_patch.dart
index 6fa4fc6..8e7e85e 100644
--- a/sdk/lib/_internal/wasm/lib/js_util_wasm_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/js_util_wasm_patch.dart
@@ -5,33 +5,17 @@
 library dart.js_util_wasm;
 
 import "dart:_internal";
-import "dart:js_util_wasm";
+import "dart:_js_helper";
 import "dart:wasm";
 
-/// js_util_wasm methods used by the wasm runtime.
-@pragma("wasm:export", "\$listLength")
-double _listLength(List list) => list.length.toDouble();
-
-@pragma("wasm:export", "\$listRead")
-WasmAnyRef? _listRead(List<Object?> list, double index) =>
-    jsifyRaw(list[index.toInt()]);
-
-@pragma("wasm:export", "\$listAllocate")
-List<Object?> _listAllocate() => [];
-
-@pragma("wasm:export", "\$listAdd")
-void _listAdd(List<Object?> list, WasmAnyRef? item) =>
-    list.add(dartifyRaw(item));
-
-@pragma("wasm:export", "\$boxJSValue")
-JSValue _boxJSValue(WasmAnyRef ref) => JSValue(ref);
-
 @patch
-Object _jsObjectToDartObject(WasmAnyRef ref) => unsafeCastOpaque<Object>(ref);
+Object allowInterop<F extends Function>(F f) => throw 'unreachable';
 
-@patch
-WasmAnyRef _jsObjectFromDartObject(Object object) =>
-    unsafeCastOpaque<WasmAnyRef>(object);
+@pragma("wasm:import", "dart2wasm.wrapDartCallback")
+external WasmAnyRef _wrapDartCallbackRaw(
+    WasmAnyRef callback, WasmAnyRef trampolineName);
 
-@patch
-JSValue allowInterop<F extends Function>(F f) => throw 'unreachable';
+JSValue? _wrapDartCallback(Object callback, String trampolineName) {
+  return JSValue(_wrapDartCallbackRaw(
+      callback.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
+}
diff --git a/sdk/lib/js_util/js_util_wasm.dart b/sdk/lib/js_util/js_util_wasm.dart
index 88c419d..0e42a86 100644
--- a/sdk/lib/js_util/js_util_wasm.dart
+++ b/sdk/lib/js_util/js_util_wasm.dart
@@ -5,177 +5,4 @@
 // Prototype js util library for wasm.
 library dart.js_util_wasm;
 
-import 'dart:wasm';
-
-/// [JSValue] is the root of the JS interop object hierarchy.
-class JSValue {
-  final WasmAnyRef _ref;
-
-  JSValue(this._ref);
-
-  static JSValue? box(WasmAnyRef? ref) => ref == null ? null : JSValue(ref);
-
-  WasmAnyRef toAnyRef() => _ref;
-  String toString() => _jsStringToDartString(_ref);
-  List<Object?> toObjectList() => _jsArrayToDartList(_ref);
-  Object toObject() => _jsObjectToDartObject(_ref);
-}
-
-/// Raw private JS functions.
-external WasmAnyRef _jsObjectFromDartObject(Object object);
-
-external Object _jsObjectToDartObject(WasmAnyRef ref);
-
-@pragma("wasm:import", "dart2wasm.arrayFromDartList")
-external WasmAnyRef _jsArrayFromDartList(List<Object?> list);
-
-@pragma("wasm:import", "dart2wasm.arrayToDartList")
-external List<Object?> _jsArrayToDartList(WasmAnyRef list);
-
-@pragma("wasm:import", "dart2wasm.stringFromDartString")
-external WasmAnyRef _jsStringFromDartString(String string);
-
-@pragma("wasm:import", "dart2wasm.stringToDartString")
-external String _jsStringToDartString(WasmAnyRef string);
-
-@pragma("wasm:import", "dart2wasm.wrapDartCallback")
-external WasmAnyRef _wrapDartCallbackRaw(
-    WasmAnyRef callback, WasmAnyRef trampolineName);
-
-JSValue? _wrapDartCallback(Object callback, String trampolineName) {
-  return JSValue(_wrapDartCallbackRaw(
-      callback.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
-}
-
-/// Raw public JS functions.
-/// These are public temporarily to give performance conscious users an escape
-/// hatch while we decide what this API will actually look like. They may
-/// become private in the future, or disappear entirely. For descriptions of the
-/// API, please see the corresponding non-raw functions.
-@pragma("wasm:import", "dart2wasm.eval")
-external void evalRaw(WasmAnyRef code);
-
-@pragma("wasm:import", "dart2wasm.dartify")
-external WasmAnyRef? dartifyRaw(WasmAnyRef? object);
-
-@pragma("wasm:import", "dart2wasm.newObject")
-external WasmAnyRef newObjectRaw();
-
-@pragma("wasm:import", "dart2wasm.globalThis")
-external WasmAnyRef globalThisRaw();
-
-@pragma("wasm:import", "dart2wasm.callConstructorVarArgs")
-external WasmAnyRef callConstructorVarArgsRaw(
-    WasmAnyRef o, WasmAnyRef name, WasmAnyRef args);
-
-@pragma("wasm:import", "dart2wasm.hasProperty")
-external bool hasPropertyRaw(WasmAnyRef o, WasmAnyRef name);
-
-@pragma("wasm:import", "dart2wasm.getProperty")
-external WasmAnyRef? getPropertyRaw(WasmAnyRef o, WasmAnyRef name);
-
-@pragma("wasm:import", "dart2wasm.setProperty")
-external WasmAnyRef? setPropertyRaw(
-    WasmAnyRef o, WasmAnyRef name, WasmAnyRef? value);
-
-@pragma("wasm:import", "dart2wasm.callMethodVarArgs")
-external WasmAnyRef? callMethodVarArgsRaw(
-    WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
-
-WasmAnyRef? jsifyRaw(Object? object) {
-  if (object == null) {
-    return null;
-  } else if (object is JSValue) {
-    return object.toAnyRef();
-  } else if (object is String) {
-    return _jsStringFromDartString(object);
-  } else if (object is List<Object?>) {
-    return _jsArrayFromDartList(object);
-  } else {
-    return _jsObjectFromDartObject(object);
-  }
-}
-
-/// Conversion functions.
-/// TODO(joshualitt): Only a small set of types currently work:
-///   JS -> Dart:
-///     null
-///     strings
-///     arrays
-///     opaque Dart objects passed to JS
-///   Dart -> JS:
-///     null
-///     boolean
-///     doubles
-///     strings
-///     lists
-///     opaque JS objects passed to Dart
-/// In the future we would like to support more types, at least maps,
-/// and to fix some of the issues returning some types from JS.
-
-/// Extension methods for conversions.
-extension StringToJS on String {
-  JSValue toJS() => JSValue(_jsStringFromDartString(this));
-}
-
-extension ListOfObjectToJS on List<Object?> {
-  JSValue toJS() => JSValue(_jsArrayFromDartList(this));
-}
-
-extension ObjectToJS on Object {
-  JSValue toJS() => JSValue(_jsObjectFromDartObject(this));
-}
-
-/// Recursively converts objects from Dart to JS.
-JSValue? jsify(Object? object) => JSValue.box(jsifyRaw(object));
-
-/// Recursively converts objects from JS to Dart.
-Object? dartify(JSValue? object) => object == null
-    ? null
-    : _jsObjectToDartObject(dartifyRaw(object.toAnyRef())!);
-
-/// js util methods.
-/// These are low level calls into JS, and require care to use correctly.
-
-/// Evals a snippet of JS code in a Dart string.
-void eval(String code) => evalRaw(code.toJS().toAnyRef());
-
-/// Creates a new JS object literal and returns it.
-JSValue newObject() => JSValue(newObjectRaw());
-
-/// Returns a reference to `globalThis`.
-JSValue globalThis() => JSValue(globalThisRaw());
-
-/// Gets a [String] name property off of a JS object [o], invokes it as
-/// a constructor with a JS array of arguments [args], and returns the
-/// constructed JS object.
-JSValue callConstructorVarArgs(JSValue o, String name, List<JSValue?> args) =>
-    JSValue(callConstructorVarArgsRaw(
-        o.toAnyRef(), name.toJS().toAnyRef(), args.toJS().toAnyRef()));
-
-/// Checks for a [String] name on a JS object [o].
-bool hasProperty(JSValue o, String name) =>
-    hasPropertyRaw(o.toAnyRef(), name.toJS().toAnyRef());
-
-/// Gets a JS property with [String] name off of a JS object [o].
-JSValue? getProperty(JSValue o, String name) =>
-    JSValue.box(getPropertyRaw(o.toAnyRef(), name.toJS().toAnyRef()));
-
-/// Sets a JS property with [String] name on JS object [o] to the JS value
-/// [value], then returns [value].
-JSValue? setProperty(JSValue o, String name, JSValue? value) => JSValue.box(
-    setPropertyRaw(o.toAnyRef(), name.toJS().toAnyRef(), value?.toAnyRef()));
-
-/// Calls a JS method with a [String] name on JS object [o] with a JS array
-/// of arguments [args] and returns the resulting JS value.
-JSValue? callMethodVarArgs(JSValue o, String method, List<JSValue?> args) =>
-    JSValue.box(callMethodVarArgsRaw(
-        o.toAnyRef(), method.toJS().toAnyRef(), args.toJS().toAnyRef()));
-
-/// Returns a wrapped version of [f] suitable for calling from JS. Use [dartify]
-/// to convert back to Dart.
-/// TODO(joshualitt): This is significantly different from the implementation of
-/// [allowInterop] on other web backends. We will need to come up with a unified
-/// semantics or Dart programs will not be able to work correctly across
-/// different web backends.
-external JSValue allowInterop<F extends Function>(F f);
+external Object allowInterop<F extends Function>(F f);
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 8da8878..8f68164 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -168,6 +168,9 @@
           "_internal/vm/lib/symbol_patch.dart"
         ]
       },
+      "_js_helper": {
+        "uri": "_internal/wasm/lib/js_helper.dart"
+      },
       "async": {
         "uri": "async/async.dart",
         "patches": "_internal/wasm/lib/timer_patch.dart"
@@ -232,6 +235,10 @@
       "isolate": {
         "uri": "isolate/isolate.dart"
       },
+      "js_util": {
+        "uri": "js_util/js_util.dart",
+        "patches": "_internal/wasm/lib/js_util_patch.dart"
+      },
       "js_util_wasm": {
         "uri": "js_util/js_util_wasm.dart",
         "patches": "_internal/wasm/lib/js_util_wasm_patch.dart"
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index fea4da3..97d0351 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -164,6 +164,8 @@
       - _internal/wasm/lib/patch.dart
       - _internal/wasm/lib/print_patch.dart
       - _internal/vm/lib/symbol_patch.dart
+    _js_helper:
+      uri: _internal/wasm/lib/js_helper.dart
     async:
       uri: async/async.dart
       patches: _internal/wasm/lib/timer_patch.dart
@@ -216,6 +218,9 @@
       uri: "html/dartium/nativewrappers.dart"
     isolate:
       uri: isolate/isolate.dart
+    js_util:
+      uri: js_util/js_util.dart
+      patches: _internal/wasm/lib/js_util_patch.dart
     js_util_wasm:
       uri: js_util/js_util_wasm.dart
       patches: _internal/wasm/lib/js_util_wasm_patch.dart
diff --git a/tests/language/switch/backward_jump_test.dart b/tests/language/switch/backward_jump_test.dart
new file mode 100644
index 0000000..d4bc491
--- /dev/null
+++ b/tests/language/switch/backward_jump_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.
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals(test(5), 'a');
+  Expect.equals(test(10), 'a through b');
+  Expect.equals(test(7), 'b');
+}
+
+String test(int i) {
+  switch (i) {
+    a:
+    case 5:
+      {
+        if (i == 10) {
+          return 'a through b';
+        }
+        if (i == 0) {
+          return 'a';
+        }
+        i -= 1;
+        continue a; // backward jump to non-default self
+      }
+
+    b:
+    default:
+      {
+        if (i == 10) {
+          continue a; // backward jump to non-default
+        }
+        if (i == 0) {
+          return 'b';
+        }
+        i -= 1;
+        continue b; // backward jump to default
+      }
+  }
+}
diff --git a/tests/language_2/switch/backward_jump_test.dart b/tests/language_2/switch/backward_jump_test.dart
new file mode 100644
index 0000000..d4bc491
--- /dev/null
+++ b/tests/language_2/switch/backward_jump_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.
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals(test(5), 'a');
+  Expect.equals(test(10), 'a through b');
+  Expect.equals(test(7), 'b');
+}
+
+String test(int i) {
+  switch (i) {
+    a:
+    case 5:
+      {
+        if (i == 10) {
+          return 'a through b';
+        }
+        if (i == 0) {
+          return 'a';
+        }
+        i -= 1;
+        continue a; // backward jump to non-default self
+      }
+
+    b:
+    default:
+      {
+        if (i == 10) {
+          continue a; // backward jump to non-default
+        }
+        if (i == 0) {
+          return 'b';
+        }
+        i -= 1;
+        continue b; // backward jump to default
+      }
+  }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 6d0cacd4..905ce63 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -7,7 +7,6 @@
 # prefix.
 io/http_close_stack_overflow_test: Skip # The test is heavy loaded. Should be used for manual test.
 io/http_linklocal_ipv6_test: SkipByDesign # This needs manual test.
-io/large_file_read_small_file_test: Slow # Test reads small file 1M times
 io/non_utf8_directory_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_file_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_link_test: Skip # Issue 33519. Temp files causing bots to go purple.
@@ -75,6 +74,9 @@
 io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
 
+[ $system == windows ]
+io/large_file_read_small_file_test: Slow # Test reads small file 1M times
+
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
 
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index fba85b6..5e3852e 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -7,7 +7,6 @@
 # prefix.
 io/http_close_stack_overflow_test: Skip # The test is heavy loaded. Should be used for manual test.
 io/http_linklocal_ipv6_test: SkipByDesign # This needs manual test.
-io/large_file_read_small_file_test: Slow # Test reads small file 1M times
 io/non_utf8_directory_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_file_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_link_test: Skip # Issue 33519. Temp files causing bots to go purple.
@@ -85,6 +84,9 @@
 io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
 
+[ $system == windows ]
+io/large_file_read_small_file_test: Slow # Test reads small file 1M times
+
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
 
diff --git a/tests/web/wasm/callback_test.dart b/tests/web/wasm/callback_test.dart
index 63e5ba1..dbd421f 100644
--- a/tests/web/wasm/callback_test.dart
+++ b/tests/web/wasm/callback_test.dart
@@ -2,24 +2,29 @@
 // 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:js_util';
 import 'dart:js_util_wasm';
 import 'dart:js_wasm';
 import 'dart:wasm';
 
 import 'package:expect/expect.dart';
 
+@JS()
+external void eval(String code);
+
 typedef SumStringCallback = String Function(String a, String b);
 
 @JS()
 @staticInterop
 class DartFromJSCallbackHelper {
-  external factory DartFromJSCallbackHelper.factory(SumStringCallback summer);
+  // TODO(joshualitt): Update [allowInterop] to return a function.
+  external factory DartFromJSCallbackHelper.factory(Object summer);
 }
 
 extension DartFromJSCallbackHelperMethods on DartFromJSCallbackHelper {
   external String doSum1();
   external String doSum2(String a, String b);
-  external String doSum3(SumStringCallback summer);
+  external String doSum3(Object summer);
 }
 
 String sumString(String a, String b) {
@@ -45,11 +50,14 @@
     }
   ''');
 
-  final dartFromJSCallbackHelper = DartFromJSCallbackHelper.factory(sumString);
+  final dartFromJSCallbackHelper = DartFromJSCallbackHelper.factory(
+      allowInterop<SumStringCallback>(sumString));
   Expect.equals('hello world!', dartFromJSCallbackHelper.doSum1());
   Expect.equals('foobar', dartFromJSCallbackHelper.doSum2('foo', 'bar'));
   Expect.equals(
-      'hello world!', dartFromJSCallbackHelper.doSum3((a, b) => a + b));
+      'hello world!',
+      dartFromJSCallbackHelper
+          .doSum3(allowInterop<SumStringCallback>((a, b) => a + b)));
 }
 
 void allowInteropCallbackTest() {
@@ -63,14 +71,12 @@
   ''');
 
   final interopCallback = allowInterop<SumStringCallback>((a, b) => a + b);
-  Expect.equals('foobar',
-      callMethodVarArgs(globalThis(), 'doSum1', [interopCallback]).toString());
-  setProperty(globalThis(), 'summer', interopCallback);
   Expect.equals(
-      'foobar',
-      callMethodVarArgs(globalThis(), 'doSum2', ['foo'.toJS(), 'bar'.toJS()])
-          .toString());
-  final roundTripCallback = getProperty(globalThis(), 'summer');
+      'foobar', callMethod(globalThis, 'doSum1', [interopCallback]).toString());
+  setProperty(globalThis, 'summer', interopCallback);
+  Expect.equals(
+      'foobar', callMethod(globalThis, 'doSum2', ['foo', 'bar']).toString());
+  final roundTripCallback = getProperty(globalThis, 'summer');
   Expect.equals('foobar',
       (dartify(roundTripCallback) as SumStringCallback)('foo', 'bar'));
 }
diff --git a/tests/web/wasm/js_util_test.dart b/tests/web/wasm/js_util_test.dart
index a5b31c1..388a1eb 100644
--- a/tests/web/wasm/js_util_test.dart
+++ b/tests/web/wasm/js_util_test.dart
@@ -2,16 +2,20 @@
 // 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:js_util_wasm';
+import 'dart:js_util';
+import 'dart:js_wasm';
 
 import 'package:expect/expect.dart';
 
+@JS()
+external void eval(String code);
+
 void createObjectTest() {
-  JSValue o = newObject();
+  Object o = newObject();
   Expect.isFalse(hasProperty(o, 'foo'));
-  Expect.equals('bar', setProperty(o, 'foo', 'bar'.toJS()).toString());
+  Expect.equals('bar', setProperty(o, 'foo', 'bar'));
   Expect.isTrue(hasProperty(o, 'foo'));
-  Expect.equals('bar', getProperty(o, 'foo').toString());
+  Expect.equals('bar', getProperty(o, 'foo'));
 }
 
 // Unfortunately, lists do not currently compare identically.
@@ -33,14 +37,12 @@
     }
     globalThis.JSClass = JSClass;
   ''');
-  JSValue gt = globalThis();
-  JSValue jsClass = callConstructorVarArgs(gt, 'JSClass', ['world!'.toJS()]);
-  Expect.equals(
-      'hello world!',
-      callMethodVarArgs(jsClass, 'sum', ['hello'.toJS(), ' '.toJS()])
-          .toString());
+  Object gt = globalThis;
+  Object constructor = getProperty(gt, 'JSClass');
+  Object jsClass = callConstructor(constructor, ['world!']);
+  Expect.equals('hello world!', callMethod(jsClass, 'sum', ['hello', ' ']));
   _expectListEquals(
-      ['a', 'b', 'c'], getProperty(jsClass, 'list')!.toObjectList());
+      ['a', 'b', 'c'], getProperty(jsClass, 'list') as List<Object?>);
 }
 
 class Foo {
@@ -49,15 +51,16 @@
 }
 
 void dartObjectRoundTripTest() {
-  JSValue o = newObject();
-  setProperty(o, 'foo', Foo(4).toJS());
-  Object foo = getProperty(o, 'foo')!.toObject();
+  Object o = newObject();
+  setProperty(o, 'foo', Foo(4));
+  Object foo = getProperty(o, 'foo')!;
   Expect.equals(4, (foo as Foo).i);
 }
 
 void deepConversionsTest() {
   // Dart to JS.
-  Expect.isNull(dartify(jsify(null)));
+  // TODO(joshualitt): Consider supporting `null` in jsify.
+  // Expect.isNull(dartify(jsify(null)));
   Expect.equals(true, dartify(jsify(true)));
   Expect.equals(2.0, dartify(jsify(2.0)));
   Expect.equals('foo', dartify(jsify('foo')));
@@ -70,7 +73,7 @@
     globalThis.b = 'foo';
     globalThis.c = ['a', 'b', 'c'];
   ''');
-  JSValue gt = globalThis();
+  Object gt = globalThis;
   Expect.isNull(dartify(getProperty(gt, 'a')));
   Expect.equals('foo', dartify(getProperty(gt, 'b')));
   _expectListEquals(
diff --git a/tests/web/wasm/static_interop_test.dart b/tests/web/wasm/static_interop_test.dart
index 97bb80f..7c587a0 100644
--- a/tests/web/wasm/static_interop_test.dart
+++ b/tests/web/wasm/static_interop_test.dart
@@ -7,6 +7,9 @@
 
 import 'package:expect/expect.dart';
 
+@JS()
+external void eval(String code);
+
 @JS('JSClass')
 @staticInterop
 class StaticJSClass {
diff --git a/tools/VERSION b/tools/VERSION
index 47b9487..b52bd2e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 170
+PRERELEASE 171
 PRERELEASE_PATCH 0
\ No newline at end of file