[cfe] Introduce Kernel AST node for the closure expreiment

Part of https://github.com/dart-lang/sdk/issues/61572

Change-Id: Iee3c2a223f4c44f5528016082cf3a068b401d87d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/454061
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/kernel/hierarchy/mixin_inferrer.dart b/pkg/front_end/lib/src/kernel/hierarchy/mixin_inferrer.dart
index 31f413c..e35a495 100644
--- a/pkg/front_end/lib/src/kernel/hierarchy/mixin_inferrer.dart
+++ b/pkg/front_end/lib/src/kernel/hierarchy/mixin_inferrer.dart
@@ -10,7 +10,7 @@
 
 import '../../base/messages.dart'
     show Message, codeMixinInferenceNoMatchingClass;
-import '../../base/problems.dart' show unexpected, unsupported;
+import '../../base/problems.dart' show unexpected, unimplemented, unsupported;
 import '../../source/source_class_builder.dart';
 import '../../type_inference/type_schema.dart';
 
@@ -223,6 +223,15 @@
       classBuilder.fileUri,
     );
   }
+
+  // Coverage-ignore(suite): Not run.
+  Never reportUnimplementedProblem(String operation) {
+    return unimplemented(
+      operation,
+      classBuilder.fileOffset,
+      classBuilder.fileUri,
+    );
+  }
 }
 
 class _MixinInferenceSolution {
@@ -447,6 +456,22 @@
         } else {
           return <TypeParameter, DartType>{};
         }
+      case FunctionTypeParameterType():
+        // Coverage-ignore(suite): Not run.
+        // Type variable types are currently an experiment aren't fully
+        // implemented.
+        return unsupportedErrorReporter.reportUnimplementedProblem(
+          "_MixinInferenceSolution._solveForEquality"
+          "(${type1.runtimeType}, ${type2.runtimeType})",
+        );
+      case ClassTypeParameterType():
+        // Coverage-ignore(suite): Not run.
+        // Class type parameter types are currently an experiment aren't fully
+        // implemented.
+        return unsupportedErrorReporter.reportUnimplementedProblem(
+          "_MixinInferenceSolution._solveForEquality"
+          "(${type1.runtimeType}, ${type2.runtimeType})",
+        );
       case RecordType():
         // Coverage-ignore(suite): Not run.
         if (type2 is! RecordType) {
diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart
index da3b2e1..4503367 100644
--- a/pkg/front_end/lib/src/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/kernel/internal_ast.dart
@@ -398,7 +398,7 @@
       printer.newLine();
     }
     printer.write('} => ');
-    printer.write(printer.getVariableName(variable));
+    printer.write(printer.getVariableDeclarationName(variable));
   }
 }
 
diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
index a7a1255..a4df663 100644
--- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
@@ -26,7 +26,7 @@
 import '../base/messages.dart';
 import '../base/problems.dart'
     as problems
-    show internalProblem, unhandled, unsupported;
+    show internalProblem, unhandled, unimplemented, unsupported;
 import '../base/uri_offset.dart';
 import '../builder/library_builder.dart';
 import '../dill/dill_library_builder.dart';
@@ -1100,6 +1100,20 @@
           return _isIncompatibleWithAwait(type.parameter.bound);
         case IntersectionType():
           return _isIncompatibleWithAwait(type.right);
+        case FunctionTypeParameterType():
+          // Coverage-ignore(suite): Not run.
+          return problems.unimplemented(
+            "_isIncompatibleWithAwait(FunctionTypeParameterType)",
+            -1,
+            fileUri,
+          );
+        case ClassTypeParameterType():
+          // Coverage-ignore(suite): Not run.
+          return problems.unimplemented(
+            "_isIncompatibleWithAwait(ClassTypeParameterType)",
+            -1,
+            fileUri,
+          );
         case DynamicType():
         case VoidType():
         case FutureOrType():
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index d049d4e..a649777 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -948,6 +948,7 @@
 distinction
 distinguish
 distinguishes
+distinguishing
 divide
 division
 divisor
@@ -1084,6 +1085,7 @@
 enumerations
 enums
 environment
+environments
 equal
 equalities
 equality
@@ -1129,6 +1131,7 @@
 examining
 example
 examples
+exceed
 exceeded
 except
 exception
@@ -2953,6 +2956,7 @@
 split
 splits
 splitter
+spot
 spread
 spreadable
 spreads
@@ -3461,6 +3465,7 @@
 visitor
 visitor's
 visual
+visually
 vm
 void
 vowel
diff --git a/pkg/front_end/tool/ast_model.dart b/pkg/front_end/tool/ast_model.dart
index c775666..a46776a 100644
--- a/pkg/front_end/tool/ast_model.dart
+++ b/pkg/front_end/tool/ast_model.dart
@@ -148,6 +148,8 @@
   'VariablePattern': {'variable': FieldRule(isDeclaration: true)},
   'PatternSwitchCase': {'jointVariables': FieldRule(isDeclaration: true)},
   'PatternSwitchStatement': {'cases': FieldRule(isDeclaration: true)},
+  'TypeVariable': {'parameter': FieldRule(isDeclaration: false)},
+  'ClassTypeParameterType': {'parameter': FieldRule(isDeclaration: false)},
 };
 
 /// Data that determines exceptions to how fields are used.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 1565fe9..d304b91 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -124,3 +124,4 @@
 part 'src/ast/statements.dart';
 part 'src/ast/typedefs.dart';
 part 'src/ast/types.dart';
+part 'src/ast/variables.dart';
diff --git a/pkg/kernel/lib/src/ast/expressions.dart b/pkg/kernel/lib/src/ast/expressions.dart
index 29bd5d9..11b2101 100644
--- a/pkg/kernel/lib/src/ast/expressions.dart
+++ b/pkg/kernel/lib/src/ast/expressions.dart
@@ -242,7 +242,7 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
-    printer.write(printer.getVariableName(variable));
+    printer.write(printer.getVariableDeclarationName(variable));
     if (promotedType != null) {
       printer.write('{');
       printer.writeType(promotedType!);
@@ -301,7 +301,7 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
-    printer.write(printer.getVariableName(variable));
+    printer.write(printer.getVariableDeclarationName(variable));
     printer.write(' = ');
     printer.writeExpression(value);
   }
@@ -2211,7 +2211,7 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
-    printer.write(printer.getVariableName(variable));
+    printer.write(printer.getVariableDeclarationName(variable));
     printer.writeArguments(arguments);
   }
 }
@@ -4764,10 +4764,13 @@
   }
 }
 
-class BlockExpression extends Expression {
+class BlockExpression extends Expression implements ScopeProvider {
   Block body;
   Expression value;
 
+  @override
+  Scope? scope;
+
   BlockExpression(this.body, this.value) {
     body.parent = this;
     value.parent = this;
@@ -5101,3 +5104,112 @@
     printer.write(")");
   }
 }
+
+/// [VariableRead] nodes are the replacement for the VariableGet nodes.
+///
+/// Despite of the  name, [VariableRead] can't read [TypeVariable]s,
+/// which are also [Variable]s.
+class VariableRead extends Expression {
+  final ExpressionVariable variable;
+
+  VariableRead({required this.variable});
+
+  @override
+  R accept<R>(ExpressionVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  DartType getStaticTypeInternal(StaticTypeContext context) {
+    // TODO(cstefantsova): Implement getStaticTypeInternal.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "VariableRead(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write(printer.getVariableName(variable));
+  }
+}
+
+/// [VariableWrite] nodes are the replacement for the VariableSet nodes.
+///
+/// Despite of the  name, [VariableWrite] can't write into
+/// [TypeVariable]s, which are also [Variable]s.
+class VariableWrite extends Expression {
+  final ExpressionVariable variable;
+  final Expression value;
+
+  VariableWrite({required this.variable, required this.value});
+
+  @override
+  R accept<R>(ExpressionVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  DartType getStaticTypeInternal(StaticTypeContext context) {
+    // TODO(cstefantsova): Implement getStaticTypeInternal.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "VariableWrite(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write(printer.getVariableName(variable));
+    printer.write(' = ');
+    printer.writeExpression(value);
+  }
+}
diff --git a/pkg/kernel/lib/src/ast/functions.dart b/pkg/kernel/lib/src/ast/functions.dart
index 710a98c..5cdb431 100644
--- a/pkg/kernel/lib/src/ast/functions.dart
+++ b/pkg/kernel/lib/src/ast/functions.dart
@@ -12,7 +12,7 @@
 ///
 /// This may occur in a procedure, constructor, function expression, or local
 /// function declaration.
-class FunctionNode extends TreeNode {
+class FunctionNode extends TreeNode implements ScopeProvider {
   /// End offset in the source file it comes from. Valid values are from 0 and
   /// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available
   /// (this is the default if none is specifically set).
@@ -44,6 +44,9 @@
   DartType returnType; // Not null.
   Statement? _body;
 
+  @override
+  Scope? scope;
+
   /// The emitted value of non-sync functions
   ///
   /// For `async` functions [emittedValueType] is the future value type, that
diff --git a/pkg/kernel/lib/src/ast/statements.dart b/pkg/kernel/lib/src/ast/statements.dart
index 7d155da..404fd4f 100644
--- a/pkg/kernel/lib/src/ast/statements.dart
+++ b/pkg/kernel/lib/src/ast/statements.dart
@@ -82,7 +82,7 @@
   }
 }
 
-class Block extends Statement {
+class Block extends Statement implements ScopeProvider {
   final List<Statement> statements;
 
   /// End offset in the source file it comes from. Valid values are from 0 and
@@ -93,6 +93,9 @@
   @override
   List<int>? get fileOffsetsIfMultiple => [fileOffset, fileEndOffset];
 
+  @override
+  Scope? scope;
+
   Block(this.statements) {
     // Ensure statements is mutable.
     assert(checkListIsMutable(statements, dummyStatement));
@@ -526,7 +529,7 @@
   }
 }
 
-class ForStatement extends Statement implements LoopStatement {
+class ForStatement extends Statement implements LoopStatement, ScopeProvider {
   final List<VariableDeclaration> variables; // May be empty, but not null.
   Expression? condition; // May be null.
   final List<Expression> updates; // May be empty, but not null.
@@ -534,6 +537,9 @@
   @override
   Statement body;
 
+  @override
+  Scope? scope;
+
   ForStatement(this.variables, this.condition, this.updates, this.body) {
     setParents(variables, this);
     condition?.parent = this;
@@ -606,7 +612,7 @@
   }
 }
 
-class ForInStatement extends Statement implements LoopStatement {
+class ForInStatement extends Statement implements LoopStatement, ScopeProvider {
   /// Offset in the source file it comes from.
   ///
   /// Valid values are from 0 and up, or -1 ([TreeNode.noOffset]) if the file
@@ -624,6 +630,9 @@
 
   bool isAsync; // True if this is an 'await for' loop.
 
+  @override
+  Scope? scope;
+
   ForInStatement(this.variable, this.iterable, this.body,
       {this.isAsync = false}) {
     variable.parent = this;
@@ -1169,12 +1178,15 @@
   }
 }
 
-class Catch extends TreeNode {
+class Catch extends TreeNode implements ScopeProvider {
   DartType guard; // Not null, defaults to dynamic.
   VariableDeclaration? exception;
   VariableDeclaration? stackTrace;
   Statement body;
 
+  @override
+  Scope? scope;
+
   Catch(this.exception, this.body,
       {this.guard = const DynamicType(), this.stackTrace}) {
     exception?.parent = this;
@@ -1808,9 +1820,62 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
-    printer.writeFunctionNode(function, printer.getVariableName(variable));
+    printer.writeFunctionNode(
+        function, printer.getVariableDeclarationName(variable));
     if (function.body is ReturnStatement) {
       printer.write(';');
     }
   }
 }
+
+/// The statement that marks the declaration of the variable in the source Dart
+/// program. If the [initializer] is `null`, the variable was declared without
+/// an initializer.
+class VariableInitialization extends Statement {
+  final ExpressionVariable variable;
+  final Expression? initializer;
+
+  VariableInitialization({required this.variable, required this.initializer});
+
+  @override
+  R accept<R>(StatementVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(StatementVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "VariableInitialization(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write(printer.getVariableName(variable));
+    if (initializer case var initializer?) {
+      printer.write(' := ');
+      printer.writeExpression(initializer);
+    }
+    printer.write(';');
+  }
+}
diff --git a/pkg/kernel/lib/src/ast/types.dart b/pkg/kernel/lib/src/ast/types.dart
index 189f31b..4bf7fa9 100644
--- a/pkg/kernel/lib/src/ast/types.dart
+++ b/pkg/kernel/lib/src/ast/types.dart
@@ -1976,11 +1976,12 @@
 }
 
 /// Reference to a type variable.
-class TypeParameterType extends DartType {
+class TypeParameterType extends DartType implements TypeParameterTypeInterface {
   /// The declared nullability of a type-parameter type.
   @override
   Nullability declaredNullability;
 
+  @override
   final TypeParameter parameter;
 
   TypeParameterType(this.parameter, this.declaredNullability);
@@ -2299,3 +2300,189 @@
     printer.write(")");
   }
 }
+
+/// Type variables of functions.
+///
+/// [TypeVariable] represents type variables of functions, such as top-level
+/// methods, static and instance methods, local declarations, and function
+/// expressions.
+class TypeVariable extends Variable {
+  @override
+  String? cosmeticName;
+
+  /// Function type parameter this [TypeVariable] is associated with.
+  final TypeParameter parameter;
+
+  TypeVariable({this.cosmeticName, required this.parameter});
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  /// Returns a possibly synthesized name for the nominal parameter, consistent
+  /// with the names used across all [toString] calls.
+  @override
+  String toString() {
+    return "TypeVariable(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeTypeParameterName(parameter);
+  }
+}
+
+/// The shared interface between all types referring type parameters.
+abstract class TypeParameterTypeInterface {
+  TypeParameter get parameter;
+}
+
+/// A type-parameter type referring to [TypeVariable] of a function.
+class FunctionTypeParameterType extends ExperimentalType
+    implements TypeParameterTypeInterface {
+  final TypeVariable variable;
+
+  @override
+  Nullability declaredNullability;
+
+  FunctionTypeParameterType(
+      {required this.variable, required this.declaredNullability});
+
+  @override
+  TypeParameter get parameter => variable.parameter;
+
+  @override
+  R accept<R>(DartTypeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(DartTypeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  bool equals(Object other, Assumptions? assumptions) {
+    // TODO(cstefantsova): Implement equals.
+    throw UnimplementedError();
+  }
+
+  @override
+  // TODO(cstefantsova): Implement hasNonObjectMemberAccess.
+  bool get hasNonObjectMemberAccess => throw UnimplementedError();
+
+  @override
+  // TODO(cstefantsova): Implement nonTypeParameterBound.
+  DartType get nonTypeParameterBound => throw UnimplementedError();
+
+  @override
+  // TODO(cstefantsova): Implement nullability.
+  Nullability get nullability => throw UnimplementedError();
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  DartType withDeclaredNullability(Nullability declaredNullability) {
+    // TODO(cstefantsova): Implement withDeclaredNullability.
+    throw UnimplementedError();
+  }
+
+  @override
+  String toString() {
+    return "FunctionTypeParameterType(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeTypeParameterName(variable.parameter);
+    printer.writeNullability(declaredNullability);
+  }
+}
+
+/// A type-parameter type referring to [TypeParameter] of a class, mixin, or
+/// enum.
+///
+/// The generic class, mixin, or enum is accessible via [thisVariable].
+class ClassTypeParameterType extends ExperimentalType
+    implements TypeParameterTypeInterface {
+  final ThisVariable thisVariable;
+
+  @override
+  final TypeParameter parameter;
+
+  @override
+  Nullability declaredNullability;
+
+  ClassTypeParameterType(
+      {required this.thisVariable,
+      required this.parameter,
+      required this.declaredNullability});
+
+  @override
+  bool equals(Object other, Assumptions? assumptions) {
+    // TODO: implement equals
+    throw UnimplementedError();
+  }
+
+  @override
+  // TODO: implement hasNonObjectMemberAccess
+  bool get hasNonObjectMemberAccess => throw UnimplementedError();
+
+  @override
+  // TODO: implement nonTypeParameterBound
+  DartType get nonTypeParameterBound => throw UnimplementedError();
+
+  @override
+  // TODO: implement nullability
+  Nullability get nullability => throw UnimplementedError();
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    // TODO: implement visitChildren
+  }
+
+  @override
+  DartType withDeclaredNullability(Nullability declaredNullability) {
+    // TODO: implement withDeclaredNullability
+    throw UnimplementedError();
+  }
+
+  @override
+  String toString() {
+    return "ClassTypeParameterType(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeTypeParameterName(parameter);
+    printer.writeNullability(declaredNullability);
+  }
+}
diff --git a/pkg/kernel/lib/src/ast/variables.dart b/pkg/kernel/lib/src/ast/variables.dart
new file mode 100644
index 0000000..002bb31f
--- /dev/null
+++ b/pkg/kernel/lib/src/ast/variables.dart
@@ -0,0 +1,361 @@
+// Copyright (c) 2025, 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.
+
+part of '../../ast.dart';
+
+/// Generalized notion of a variable.
+sealed class Variable extends TreeNode {
+  VariableContext get context => parent as VariableContext;
+
+  // CaptureKind get captureKind => context.captureKind;
+
+  /// The cosmetic name of the variable from the source code, if exists.
+  String? get cosmeticName;
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write(printer.getVariableName(this));
+  }
+}
+
+/// The root of the sealed hierarchy of non-type variables.
+sealed class ExpressionVariable extends Variable {}
+
+/// Local variables. They aren't Statements. A [LocalVariable] is "declared" in
+/// the [VariableContext] it appears in. [VariableInitialization]
+/// (which is a [Statement]) marks the spot of the original variable declaration
+/// in the Dart program.
+class LocalVariable extends ExpressionVariable {
+  @override
+  String? cosmeticName;
+
+  LocalVariable({this.cosmeticName});
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "LocalVariable(${toStringInternal()})";
+  }
+}
+
+/// Abstract parameter class, the parent for positional and named parameters.
+sealed class FunctionParameter extends ExpressionVariable {}
+
+/// Positional parameters. The [cosmeticName] field is optional and doesn't
+/// affect the runtime semantics of the program.
+class PositionalParameter extends FunctionParameter {
+  @override
+  final String? cosmeticName;
+
+  PositionalParameter(this.cosmeticName);
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "PositionalParameter(${toStringInternal()})";
+  }
+}
+
+/// Named parameters. The [name] field is mandatory.
+class NamedParameter extends FunctionParameter {
+  final String name;
+
+  @override
+  String get cosmeticName => name;
+
+  NamedParameter({required this.name});
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "NamedParameter(${toStringInternal()})";
+  }
+}
+
+/// The variable storage for `this`.
+class ThisVariable extends ExpressionVariable {
+  @override
+  String get cosmeticName => "this";
+
+  ThisVariable();
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "ThisVariable(${toStringInternal()})";
+  }
+}
+
+/// A variable introduced during desugaring. Such variables don't correspond to
+/// any variable declared by the programmer.
+class SyntheticVariable extends ExpressionVariable {
+  @override
+  String? cosmeticName;
+
+  SyntheticVariable({this.cosmeticName});
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "SyntheticVariable(${toStringInternal()})";
+  }
+}
+
+/// The enum reflecting the kind of a variable context. A context is
+/// [assertCaptured] if it contains the variables captured in a closure within
+/// an `assert` and not captured anywhere outside of `assert`s.
+enum CaptureKind {
+  notCaptured,
+  captured,
+  assertCaptured;
+}
+
+/// The box storing some of the variables in the scope it's associated with. It
+/// serves as the "declaration" of the variables it contains for the runtime
+/// environments.
+class VariableContext extends TreeNode {
+  final CaptureKind captureKind;
+  final List<Variable> variables;
+
+  VariableContext({required this.captureKind, required this.variables});
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "VariableContext(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write('[');
+    for (int index = 0; index < variables.length; index++) {
+      if (index > 0) {
+        printer.write(', ');
+      }
+      variables[index].toTextInternal(printer);
+    }
+    printer.write(']');
+  }
+}
+
+/// The collection of the contexts pertaining to a scope-inducing node. The
+/// [Scopes] are supposed to be treated as the points of declaration of the
+/// variables they contain. They aren't [Statement]s, but a runtime may choose
+/// to interpret the [Scope] in an executable way before any [Statement]s or
+/// [Expression]s of its node.
+class Scope extends TreeNode {
+  final List<VariableContext> contexts;
+
+  Scope(this.contexts);
+
+  @override
+  R accept<R>(TreeVisitor<R> v) {
+    // TODO(cstefantsova): Implement accept.
+    throw UnimplementedError();
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> v, A arg) {
+    // TODO(cstefantsova): Implement accept1.
+    throw UnimplementedError();
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // TODO(cstefantsova): Implement transformChildren.
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // TODO(cstefantsova): Implement transformOrRemoveChildren.
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    // TODO(cstefantsova): Implement visitChildren.
+  }
+
+  @override
+  String toString() {
+    return "Scope(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write('[');
+    for (int index = 0; index < contexts.length; index++) {
+      if (index > 0) {
+        printer.write(', ');
+      }
+      contexts[index].toTextInternal(printer);
+    }
+    printer.write(']');
+  }
+}
+
+/// The root of the sealed hierarchy of the nodes that provide a scope, such as
+/// loops, functions, and blocks.
+sealed class ScopeProvider {
+  /// The scope of the [ScopeProvider].
+  ///
+  /// It's represented as nullable due to the experimental status of the
+  /// feature. When the feature isn't enabled, [scope] should return null.
+  Scope? get scope;
+}
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index dc708f4..8eab45a 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -140,6 +140,13 @@
   }
 
   @override
+  void visitClassTypeParameterType(ClassTypeParameterType node) {
+    if (typeParameters.contains(node.parameter)) {
+      occurred.add(node.parameter);
+    }
+  }
+
+  @override
   void visitAuxiliaryType(AuxiliaryType node) {
     throw new UnsupportedError(
         "Unsupported auxiliary type ${node} (${node.runtimeType}).");
@@ -150,6 +157,13 @@
     // TODO(cstefantsova): Should we have an occurrence visitor for
     // [StructuralParameter] objects.
   }
+
+  @override
+  void visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for ${node} (${node.runtimeType}).");
+  }
 }
 
 DartType instantiateToBounds(DartType type, Class objectClass) {
@@ -366,6 +380,10 @@
       return const <TypeArgumentIssue>[];
     case AuxiliaryType():
       throw new StateError("AuxiliaryType");
+    case FunctionTypeParameterType():
+      throw new StateError("FunctionTypeParameterType");
+    case ClassTypeParameterType():
+      throw new StateError("ClassTypeParameterType");
     case InvalidType():
       // Assuming the error is reported elsewhere.
       throw const <TypeArgumentIssue>[];
@@ -899,6 +917,25 @@
           computedVariances) {
     return VarianceCalculationValue.calculatedUnrelated;
   }
+
+  @override
+  VarianceCalculationValue visitFunctionTypeParameterType(
+      FunctionTypeParameterType node,
+      Map<TypeParameter, Map<DartType, VarianceCalculationValue>> arg) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for FunctionTypeParameterType "
+        "${node} (${node.runtimeType}).");
+  }
+
+  @override
+  VarianceCalculationValue visitClassTypeParameterType(
+      ClassTypeParameterType node,
+      Map<TypeParameter, Map<DartType, VarianceCalculationValue>> arg) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw UnimplementedError("Unimplemented support for ClassTypeParameterType "
+        "${node} (${node.runtimeType}).");
+  }
 }
 
 bool isGenericFunctionTypeOrAlias(DartType type) {
@@ -1011,4 +1048,20 @@
 
   @override
   bool visitVoidType(VoidType node, bool isTypeArgument) => false;
+
+  @override
+  bool visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, bool isTypeArgument) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for ${node} (${node.runtimeType}).");
+  }
+
+  @override
+  bool visitClassTypeParameterType(
+      ClassTypeParameterType node, bool isTypeArgument) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for ${node} (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/coverage.dart b/pkg/kernel/lib/src/coverage.dart
index 54ebba1..9151fba 100644
--- a/pkg/kernel/lib/src/coverage.dart
+++ b/pkg/kernel/lib/src/coverage.dart
@@ -585,6 +585,18 @@
   }
 
   @override
+  void visitVariableRead(VariableRead node) {
+    visited.add(ExpressionKind.VariableRead);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitVariableWrite(VariableWrite node) {
+    visited.add(ExpressionKind.VariableWrite);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitSwitchExpression(SwitchExpression node) {
     visited.add(ExpressionKind.SwitchExpression);
     node.visitChildren(this);
@@ -957,6 +969,12 @@
   }
 
   @override
+  void visitVariableInitialization(VariableInitialization node) {
+    visited.add(StatementKind.VariableInitialization);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitSwitchExpressionCase(SwitchExpressionCase node) {
     visited.add(NodeKind.SwitchExpressionCase);
     node.visitChildren(this);
@@ -975,6 +993,54 @@
   }
 
   @override
+  void visitTypeVariable(TypeVariable node) {
+    visited.add(NodeKind.TypeVariable);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitLocalVariable(LocalVariable node) {
+    visited.add(NodeKind.LocalVariable);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPositionalParameter(PositionalParameter node) {
+    visited.add(NodeKind.PositionalParameter);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitNamedParameter(NamedParameter node) {
+    visited.add(NodeKind.NamedParameter);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitThisVariable(ThisVariable node) {
+    visited.add(NodeKind.ThisVariable);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSyntheticVariable(SyntheticVariable node) {
+    visited.add(NodeKind.SyntheticVariable);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitVariableContext(VariableContext node) {
+    visited.add(NodeKind.VariableContext);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitScope(Scope node) {
+    visited.add(NodeKind.Scope);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitName(Name node) {
     visited.add(NodeKind.Name);
     node.visitChildren(this);
@@ -1011,6 +1077,18 @@
   }
 
   @override
+  void visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    visited.add(DartTypeKind.FunctionTypeParameterType);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitClassTypeParameterType(ClassTypeParameterType node) {
+    visited.add(DartTypeKind.ClassTypeParameterType);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitInvalidType(InvalidType node) {
     visited.add(DartTypeKind.InvalidType);
     node.visitChildren(this);
@@ -1252,20 +1330,28 @@
   Library,
   LibraryDependency,
   LibraryPart,
+  LocalVariable,
   MapLiteralEntry,
   MapPatternEntry,
   MapPatternRestEntry,
   Name,
   NamedExpression,
+  NamedParameter,
   NamedType,
   PatternGuard,
   PatternSwitchCase,
+  PositionalParameter,
+  Scope,
   StructuralParameter,
   Supertype,
   SwitchCase,
   SwitchExpressionCase,
+  SyntheticVariable,
+  ThisVariable,
   TypeParameter,
+  TypeVariable,
   Typedef,
+  VariableContext,
 }
 
 enum MemberKind {
@@ -1342,7 +1428,9 @@
   TypeLiteral,
   TypedefTearOff,
   VariableGet,
+  VariableRead,
   VariableSet,
+  VariableWrite,
 }
 
 enum InitializerKind {
@@ -1396,14 +1484,17 @@
   TryCatch,
   TryFinally,
   VariableDeclaration,
+  VariableInitialization,
   WhileStatement,
   YieldStatement,
 }
 
 enum DartTypeKind {
+  ClassTypeParameterType,
   DynamicType,
   ExtensionType,
   FunctionType,
+  FunctionTypeParameterType,
   FutureOrType,
   InterfaceType,
   IntersectionType,
diff --git a/pkg/kernel/lib/src/dart_type_equivalence.dart b/pkg/kernel/lib/src/dart_type_equivalence.dart
index 735ec598..a635b71 100644
--- a/pkg/kernel/lib/src/dart_type_equivalence.dart
+++ b/pkg/kernel/lib/src/dart_type_equivalence.dart
@@ -273,6 +273,22 @@
   }
 
   @override
+  bool visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, DartType other) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  bool visitClassTypeParameterType(
+      ClassTypeParameterType node, DartType other) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
   bool visitIntersectionType(IntersectionType node, DartType other) {
     if (other is IntersectionType) {
       return node.left.accept1(this, other.left) &&
diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart
index 6dcc99a..8505c0d 100644
--- a/pkg/kernel/lib/src/equivalence.dart
+++ b/pkg/kernel/lib/src/equivalence.dart
@@ -509,6 +509,16 @@
   }
 
   @override
+  bool visitVariableRead(VariableRead node, Node other) {
+    return strategy.checkVariableRead(this, node, other);
+  }
+
+  @override
+  bool visitVariableWrite(VariableWrite node, Node other) {
+    return strategy.checkVariableWrite(this, node, other);
+  }
+
+  @override
   bool visitSwitchExpression(SwitchExpression node, Node other) {
     return strategy.checkSwitchExpression(this, node, other);
   }
@@ -820,6 +830,11 @@
   }
 
   @override
+  bool visitVariableInitialization(VariableInitialization node, Node other) {
+    return strategy.checkVariableInitialization(this, node, other);
+  }
+
+  @override
   bool visitSwitchExpressionCase(SwitchExpressionCase node, Node other) {
     return strategy.checkSwitchExpressionCase(this, node, other);
   }
@@ -835,6 +850,46 @@
   }
 
   @override
+  bool visitTypeVariable(TypeVariable node, Node other) {
+    return strategy.checkTypeVariable(this, node, other);
+  }
+
+  @override
+  bool visitLocalVariable(LocalVariable node, Node other) {
+    return strategy.checkLocalVariable(this, node, other);
+  }
+
+  @override
+  bool visitPositionalParameter(PositionalParameter node, Node other) {
+    return strategy.checkPositionalParameter(this, node, other);
+  }
+
+  @override
+  bool visitNamedParameter(NamedParameter node, Node other) {
+    return strategy.checkNamedParameter(this, node, other);
+  }
+
+  @override
+  bool visitThisVariable(ThisVariable node, Node other) {
+    return strategy.checkThisVariable(this, node, other);
+  }
+
+  @override
+  bool visitSyntheticVariable(SyntheticVariable node, Node other) {
+    return strategy.checkSyntheticVariable(this, node, other);
+  }
+
+  @override
+  bool visitVariableContext(VariableContext node, Node other) {
+    return strategy.checkVariableContext(this, node, other);
+  }
+
+  @override
+  bool visitScope(Scope node, Node other) {
+    return strategy.checkScope(this, node, other);
+  }
+
+  @override
   bool visitName(Name node, Node other) {
     return strategy.checkName(this, node, other);
   }
@@ -865,6 +920,17 @@
   }
 
   @override
+  bool visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, Node other) {
+    return strategy.checkFunctionTypeParameterType(this, node, other);
+  }
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node, Node other) {
+    return strategy.checkClassTypeParameterType(this, node, other);
+  }
+
+  @override
   bool visitInvalidType(InvalidType node, Node other) {
     return strategy.checkInvalidType(this, node, other);
   }
@@ -3598,6 +3664,9 @@
     if (!checkBlockExpression_value(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkBlockExpression_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkBlockExpression_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -3696,6 +3765,43 @@
     return result;
   }
 
+  bool checkVariableRead(
+      EquivalenceVisitor visitor, VariableRead? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! VariableRead) return false;
+    if (other is! VariableRead) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkVariableRead_variable(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableRead_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkVariableWrite(
+      EquivalenceVisitor visitor, VariableWrite? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! VariableWrite) return false;
+    if (other is! VariableWrite) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkVariableWrite_variable(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableWrite_value(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableWrite_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
   bool checkSwitchExpression(
       EquivalenceVisitor visitor, SwitchExpression? node, Object? other) {
     if (identical(node, other)) return true;
@@ -3860,6 +3966,9 @@
     if (!checkFunctionNode_body(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkFunctionNode_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkFunctionNode_emittedValueType(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -4861,6 +4970,9 @@
     if (!checkBlock_fileEndOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkBlock_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkBlock_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -5021,6 +5133,9 @@
     if (!checkForStatement_body(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkForStatement_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkForStatement_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -5050,6 +5165,9 @@
     if (!checkForInStatement_isAsync(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkForInStatement_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkForInStatement_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -5235,6 +5353,26 @@
     return result;
   }
 
+  bool checkVariableInitialization(
+      EquivalenceVisitor visitor, VariableInitialization? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! VariableInitialization) return false;
+    if (other is! VariableInitialization) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkVariableInitialization_variable(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableInitialization_initializer(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableInitialization_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
   bool checkSwitchExpressionCase(
       EquivalenceVisitor visitor, SwitchExpressionCase? node, Object? other) {
     if (identical(node, other)) return true;
@@ -5273,6 +5411,9 @@
     if (!checkCatch_body(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkCatch_scope(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkCatch_fileOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -5315,6 +5456,144 @@
     return result;
   }
 
+  bool checkTypeVariable(
+      EquivalenceVisitor visitor, TypeVariable? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! TypeVariable) return false;
+    if (other is! TypeVariable) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkTypeVariable_cosmeticName(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkTypeVariable_parameter(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkTypeVariable_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkLocalVariable(
+      EquivalenceVisitor visitor, LocalVariable? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! LocalVariable) return false;
+    if (other is! LocalVariable) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkLocalVariable_cosmeticName(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkLocalVariable_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkPositionalParameter(
+      EquivalenceVisitor visitor, PositionalParameter? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! PositionalParameter) return false;
+    if (other is! PositionalParameter) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkPositionalParameter_cosmeticName(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkPositionalParameter_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkNamedParameter(
+      EquivalenceVisitor visitor, NamedParameter? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! NamedParameter) return false;
+    if (other is! NamedParameter) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkNamedParameter_name(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkNamedParameter_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkThisVariable(
+      EquivalenceVisitor visitor, ThisVariable? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! ThisVariable) return false;
+    if (other is! ThisVariable) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkThisVariable_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkSyntheticVariable(
+      EquivalenceVisitor visitor, SyntheticVariable? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! SyntheticVariable) return false;
+    if (other is! SyntheticVariable) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkSyntheticVariable_cosmeticName(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkSyntheticVariable_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkVariableContext(
+      EquivalenceVisitor visitor, VariableContext? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! VariableContext) return false;
+    if (other is! VariableContext) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkVariableContext_captureKind(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableContext_variables(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkVariableContext_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkScope(EquivalenceVisitor visitor, Scope? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! Scope) return false;
+    if (other is! Scope) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkScope_contexts(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkScope_fileOffset(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
   bool checkName(EquivalenceVisitor visitor, Name? node, Object? other) {
     if (identical(node, other)) return true;
     if (node is! Name) return false;
@@ -5432,6 +5711,45 @@
     return result;
   }
 
+  bool checkFunctionTypeParameterType(EquivalenceVisitor visitor,
+      FunctionTypeParameterType? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! FunctionTypeParameterType) return false;
+    if (other is! FunctionTypeParameterType) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkFunctionTypeParameterType_variable(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkFunctionTypeParameterType_declaredNullability(
+        visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
+  bool checkClassTypeParameterType(
+      EquivalenceVisitor visitor, ClassTypeParameterType? node, Object? other) {
+    if (identical(node, other)) return true;
+    if (node is! ClassTypeParameterType) return false;
+    if (other is! ClassTypeParameterType) return false;
+    visitor.pushNodeState(node, other);
+    bool result = true;
+    if (!checkClassTypeParameterType_thisVariable(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkClassTypeParameterType_parameter(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    if (!checkClassTypeParameterType_declaredNullability(
+        visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
+    visitor.popState();
+    return result;
+  }
+
   bool checkInvalidType(
       EquivalenceVisitor visitor, InvalidType? node, Object? other) {
     if (identical(node, other)) return true;
@@ -7732,6 +8050,11 @@
     return visitor.checkNodes(node.value, other.value, 'value');
   }
 
+  bool checkBlockExpression_scope(
+      EquivalenceVisitor visitor, BlockExpression node, BlockExpression other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkBlockExpression_fileOffset(
       EquivalenceVisitor visitor, BlockExpression node, BlockExpression other) {
     return checkExpression_fileOffset(visitor, node, other);
@@ -7803,6 +8126,31 @@
     return checkExpression_fileOffset(visitor, node, other);
   }
 
+  bool checkVariableRead_variable(
+      EquivalenceVisitor visitor, VariableRead node, VariableRead other) {
+    return visitor.checkNodes(node.variable, other.variable, 'variable');
+  }
+
+  bool checkVariableRead_fileOffset(
+      EquivalenceVisitor visitor, VariableRead node, VariableRead other) {
+    return checkExpression_fileOffset(visitor, node, other);
+  }
+
+  bool checkVariableWrite_variable(
+      EquivalenceVisitor visitor, VariableWrite node, VariableWrite other) {
+    return visitor.checkNodes(node.variable, other.variable, 'variable');
+  }
+
+  bool checkVariableWrite_value(
+      EquivalenceVisitor visitor, VariableWrite node, VariableWrite other) {
+    return visitor.checkNodes(node.value, other.value, 'value');
+  }
+
+  bool checkVariableWrite_fileOffset(
+      EquivalenceVisitor visitor, VariableWrite node, VariableWrite other) {
+    return checkExpression_fileOffset(visitor, node, other);
+  }
+
   bool checkSwitchExpression_expression(EquivalenceVisitor visitor,
       SwitchExpression node, SwitchExpression other) {
     return visitor.checkNodes(node.expression, other.expression, 'expression');
@@ -7956,6 +8304,11 @@
     return visitor.checkNodes(node.body, other.body, 'body');
   }
 
+  bool checkFunctionNode_scope(
+      EquivalenceVisitor visitor, FunctionNode node, FunctionNode other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkFunctionNode_emittedValueType(
       EquivalenceVisitor visitor, FunctionNode node, FunctionNode other) {
     return visitor.checkNodes(
@@ -9031,6 +9384,10 @@
         node.fileEndOffset, other.fileEndOffset, 'fileEndOffset');
   }
 
+  bool checkBlock_scope(EquivalenceVisitor visitor, Block node, Block other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkBlock_fileOffset(
       EquivalenceVisitor visitor, Block node, Block other) {
     return checkStatement_fileOffset(visitor, node, other);
@@ -9151,6 +9508,11 @@
     return visitor.checkNodes(node.body, other.body, 'body');
   }
 
+  bool checkForStatement_scope(
+      EquivalenceVisitor visitor, ForStatement node, ForStatement other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkForStatement_fileOffset(
       EquivalenceVisitor visitor, ForStatement node, ForStatement other) {
     return checkStatement_fileOffset(visitor, node, other);
@@ -9181,6 +9543,11 @@
     return visitor.checkValues(node.isAsync, other.isAsync, 'isAsync');
   }
 
+  bool checkForInStatement_scope(
+      EquivalenceVisitor visitor, ForInStatement node, ForInStatement other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkForInStatement_fileOffset(
       EquivalenceVisitor visitor, ForInStatement node, ForInStatement other) {
     return checkStatement_fileOffset(visitor, node, other);
@@ -9337,6 +9704,22 @@
     return checkStatement_fileOffset(visitor, node, other);
   }
 
+  bool checkVariableInitialization_variable(EquivalenceVisitor visitor,
+      VariableInitialization node, VariableInitialization other) {
+    return visitor.checkNodes(node.variable, other.variable, 'variable');
+  }
+
+  bool checkVariableInitialization_initializer(EquivalenceVisitor visitor,
+      VariableInitialization node, VariableInitialization other) {
+    return visitor.checkNodes(
+        node.initializer, other.initializer, 'initializer');
+  }
+
+  bool checkVariableInitialization_fileOffset(EquivalenceVisitor visitor,
+      VariableInitialization node, VariableInitialization other) {
+    return checkStatement_fileOffset(visitor, node, other);
+  }
+
   bool checkSwitchExpressionCase_patternGuard(EquivalenceVisitor visitor,
       SwitchExpressionCase node, SwitchExpressionCase other) {
     return visitor.checkNodes(
@@ -9371,6 +9754,10 @@
     return visitor.checkNodes(node.body, other.body, 'body');
   }
 
+  bool checkCatch_scope(EquivalenceVisitor visitor, Catch node, Catch other) {
+    return visitor.checkNodes(node.scope, other.scope, 'scope');
+  }
+
   bool checkCatch_fileOffset(
       EquivalenceVisitor visitor, Catch node, Catch other) {
     return checkTreeNode_fileOffset(visitor, node, other);
@@ -9413,6 +9800,114 @@
     return checkTreeNode_fileOffset(visitor, node, other);
   }
 
+  bool checkTypeVariable_cosmeticName(
+      EquivalenceVisitor visitor, TypeVariable node, TypeVariable other) {
+    return visitor.checkValues(
+        node.cosmeticName, other.cosmeticName, 'cosmeticName');
+  }
+
+  bool checkTypeVariable_parameter(
+      EquivalenceVisitor visitor, TypeVariable node, TypeVariable other) {
+    return visitor.checkDeclarations(
+        node.parameter, other.parameter, 'parameter');
+  }
+
+  bool checkVariable_fileOffset(
+      EquivalenceVisitor visitor, Variable node, Variable other) {
+    return checkTreeNode_fileOffset(visitor, node, other);
+  }
+
+  bool checkTypeVariable_fileOffset(
+      EquivalenceVisitor visitor, TypeVariable node, TypeVariable other) {
+    return checkVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkLocalVariable_cosmeticName(
+      EquivalenceVisitor visitor, LocalVariable node, LocalVariable other) {
+    return visitor.checkValues(
+        node.cosmeticName, other.cosmeticName, 'cosmeticName');
+  }
+
+  bool checkExpressionVariable_fileOffset(EquivalenceVisitor visitor,
+      ExpressionVariable node, ExpressionVariable other) {
+    return checkVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkLocalVariable_fileOffset(
+      EquivalenceVisitor visitor, LocalVariable node, LocalVariable other) {
+    return checkExpressionVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkPositionalParameter_cosmeticName(EquivalenceVisitor visitor,
+      PositionalParameter node, PositionalParameter other) {
+    return visitor.checkValues(
+        node.cosmeticName, other.cosmeticName, 'cosmeticName');
+  }
+
+  bool checkFunctionParameter_fileOffset(EquivalenceVisitor visitor,
+      FunctionParameter node, FunctionParameter other) {
+    return checkExpressionVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkPositionalParameter_fileOffset(EquivalenceVisitor visitor,
+      PositionalParameter node, PositionalParameter other) {
+    return checkFunctionParameter_fileOffset(visitor, node, other);
+  }
+
+  bool checkNamedParameter_name(
+      EquivalenceVisitor visitor, NamedParameter node, NamedParameter other) {
+    return visitor.checkValues(node.name, other.name, 'name');
+  }
+
+  bool checkNamedParameter_fileOffset(
+      EquivalenceVisitor visitor, NamedParameter node, NamedParameter other) {
+    return checkFunctionParameter_fileOffset(visitor, node, other);
+  }
+
+  bool checkThisVariable_fileOffset(
+      EquivalenceVisitor visitor, ThisVariable node, ThisVariable other) {
+    return checkExpressionVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkSyntheticVariable_cosmeticName(EquivalenceVisitor visitor,
+      SyntheticVariable node, SyntheticVariable other) {
+    return visitor.checkValues(
+        node.cosmeticName, other.cosmeticName, 'cosmeticName');
+  }
+
+  bool checkSyntheticVariable_fileOffset(EquivalenceVisitor visitor,
+      SyntheticVariable node, SyntheticVariable other) {
+    return checkExpressionVariable_fileOffset(visitor, node, other);
+  }
+
+  bool checkVariableContext_captureKind(
+      EquivalenceVisitor visitor, VariableContext node, VariableContext other) {
+    return visitor.checkValues(
+        node.captureKind, other.captureKind, 'captureKind');
+  }
+
+  bool checkVariableContext_variables(
+      EquivalenceVisitor visitor, VariableContext node, VariableContext other) {
+    return visitor.checkLists(
+        node.variables, other.variables, visitor.checkNodes, 'variables');
+  }
+
+  bool checkVariableContext_fileOffset(
+      EquivalenceVisitor visitor, VariableContext node, VariableContext other) {
+    return checkTreeNode_fileOffset(visitor, node, other);
+  }
+
+  bool checkScope_contexts(
+      EquivalenceVisitor visitor, Scope node, Scope other) {
+    return visitor.checkLists(
+        node.contexts, other.contexts, visitor.checkNodes, 'contexts');
+  }
+
+  bool checkScope_fileOffset(
+      EquivalenceVisitor visitor, Scope node, Scope other) {
+    return checkTreeNode_fileOffset(visitor, node, other);
+  }
+
   bool checkName_text(EquivalenceVisitor visitor, Name node, Name other) {
     return visitor.checkValues(node.text, other.text, 'text');
   }
@@ -9503,6 +9998,39 @@
         visitor.checkNodes, 'typeArguments');
   }
 
+  bool checkFunctionTypeParameterType_variable(EquivalenceVisitor visitor,
+      FunctionTypeParameterType node, FunctionTypeParameterType other) {
+    return visitor.checkNodes(node.variable, other.variable, 'variable');
+  }
+
+  bool checkFunctionTypeParameterType_declaredNullability(
+      EquivalenceVisitor visitor,
+      FunctionTypeParameterType node,
+      FunctionTypeParameterType other) {
+    return visitor.checkValues(node.declaredNullability,
+        other.declaredNullability, 'declaredNullability');
+  }
+
+  bool checkClassTypeParameterType_thisVariable(EquivalenceVisitor visitor,
+      ClassTypeParameterType node, ClassTypeParameterType other) {
+    return visitor.checkNodes(
+        node.thisVariable, other.thisVariable, 'thisVariable');
+  }
+
+  bool checkClassTypeParameterType_parameter(EquivalenceVisitor visitor,
+      ClassTypeParameterType node, ClassTypeParameterType other) {
+    return visitor.checkDeclarations(
+        node.parameter, other.parameter, 'parameter');
+  }
+
+  bool checkClassTypeParameterType_declaredNullability(
+      EquivalenceVisitor visitor,
+      ClassTypeParameterType node,
+      ClassTypeParameterType other) {
+    return visitor.checkValues(node.declaredNullability,
+        other.declaredNullability, 'declaredNullability');
+  }
+
   bool checkNeverType_declaredNullability(
       EquivalenceVisitor visitor, NeverType node, NeverType other) {
     return visitor.checkValues(node.declaredNullability,
diff --git a/pkg/kernel/lib/src/find_type_visitor.dart b/pkg/kernel/lib/src/find_type_visitor.dart
index 2def613..a247e54 100644
--- a/pkg/kernel/lib/src/find_type_visitor.dart
+++ b/pkg/kernel/lib/src/find_type_visitor.dart
@@ -97,4 +97,18 @@
 
   @override
   bool visitVoidType(VoidType node) => false;
+
+  @override
+  bool visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/future_value_type.dart b/pkg/kernel/lib/src/future_value_type.dart
index 72437f6..89d3778 100644
--- a/pkg/kernel/lib/src/future_value_type.dart
+++ b/pkg/kernel/lib/src/future_value_type.dart
@@ -122,4 +122,20 @@
     // futureValueType(void) = void.
     return node;
   }
+
+  @override
+  DartType visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, CoreTypes arg) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitClassTypeParameterType(
+      ClassTypeParameterType node, CoreTypes arg) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index 4303645..06c8c9b 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -427,4 +427,20 @@
     throw new UnsupportedError(
         "Unsupported auxiliary type ${a} (${a.runtimeType}).");
   }
+
+  @override
+  DartType? visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, DartType arg) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType? visitClassTypeParameterType(
+      ClassTypeParameterType node, DartType arg) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart
index 4b3ff8d..5847b3d 100644
--- a/pkg/kernel/lib/src/node_creator.dart
+++ b/pkg/kernel/lib/src/node_creator.dart
@@ -5,6 +5,14 @@
 import '../ast.dart';
 import 'coverage.dart';
 
+Map<T, int> _createPending<T>(Iterable<T> kinds,
+    [Set<T> experimentalKinds = const {}]) {
+  return <T, int>{
+    for (T kind in kinds)
+      if (!experimentalKinds.contains(kind)) kind: 0
+  };
+}
+
 /// Helper class used to generate ASTs that contain all different nodes.
 class NodeCreator {
   final Uri _uri;
@@ -69,22 +77,28 @@
     Iterable<InitializerKind> initializers = InitializerKind.values,
     Iterable<MemberKind> members = MemberKind.values,
     Iterable<NodeKind> nodes = NodeKind.values,
-  })  : _pendingExpressions = new Map<ExpressionKind, int>.fromIterables(
-            expressions, new List<int>.filled(expressions.length, 0)),
-        _pendingStatements = new Map<StatementKind, int>.fromIterables(
-            statements, new List<int>.filled(statements.length, 0)),
-        _pendingDartTypes = new Map<DartTypeKind, int>.fromIterables(
-            dartTypes, new List<int>.filled(dartTypes.length, 0)),
-        _pendingConstants = new Map<ConstantKind, int>.fromIterables(
-            constants, new List<int>.filled(constants.length, 0)),
-        _pendingPatterns = new Map<PatternKind, int>.fromIterables(
-            patterns, new List<int>.filled(patterns.length, 0)),
-        _pendingInitializers = new Map<InitializerKind, int>.fromIterables(
-            initializers, new List<int>.filled(initializers.length, 0)),
-        _pendingMembers = new Map<MemberKind, int>.fromIterables(
-            members, new List<int>.filled(members.length, 0)),
-        _pendingNodes = new Map<NodeKind, int>.fromIterables(
-            nodes, new List<int>.filled(nodes.length, 0)),
+  })  : _pendingExpressions = _createPending<ExpressionKind>(expressions,
+            {ExpressionKind.VariableRead, ExpressionKind.VariableWrite}),
+        _pendingStatements = _createPending<StatementKind>(
+            statements, {StatementKind.VariableInitialization}),
+        _pendingDartTypes = _createPending<DartTypeKind>(dartTypes, {
+          DartTypeKind.FunctionTypeParameterType,
+          DartTypeKind.ClassTypeParameterType
+        }),
+        _pendingConstants = _createPending<ConstantKind>(constants),
+        _pendingPatterns = _createPending<PatternKind>(patterns),
+        _pendingInitializers = _createPending<InitializerKind>(initializers),
+        _pendingMembers = _createPending<MemberKind>(members),
+        _pendingNodes = _createPending<NodeKind>(nodes, {
+          NodeKind.LocalVariable,
+          NodeKind.PositionalParameter,
+          NodeKind.NamedParameter,
+          NodeKind.SyntheticVariable,
+          NodeKind.ThisVariable,
+          NodeKind.TypeVariable,
+          NodeKind.VariableContext,
+          NodeKind.Scope
+        }),
         _uri = Uri.parse('test:uri') {
     _createdKinds.addAll(_pendingExpressions.keys);
     _createdKinds.addAll(_pendingStatements.keys);
@@ -314,6 +328,14 @@
         case NodeKind.PatternGuard:
         case NodeKind.PatternSwitchCase:
         case NodeKind.SwitchExpressionCase:
+        case NodeKind.LocalVariable:
+        case NodeKind.PositionalParameter:
+        case NodeKind.NamedParameter:
+        case NodeKind.SyntheticVariable:
+        case NodeKind.ThisVariable:
+        case NodeKind.TypeVariable:
+        case NodeKind.Scope:
+        case NodeKind.VariableContext:
           throw new UnimplementedError('Expected in body node $kind.');
         case NodeKind.Class:
           _needLibrary().addClass(node as Class);
@@ -1047,6 +1069,9 @@
       case ExpressionKind.PatternAssignment:
         return new PatternAssignment(_createPattern(), _createExpression())
           ..fileOffset = _needFileOffset();
+      case ExpressionKind.VariableRead:
+      case ExpressionKind.VariableWrite:
+        throw new UnimplementedError("Unimplemented support for ${kind}.");
     }
   }
 
@@ -1344,6 +1369,8 @@
               isFinal: true)
             ..fileOffset = _needFileOffset(),
         ]);
+      case StatementKind.VariableInitialization:
+        throw new UnimplementedError("Unimplemented support for ${kind}.");
     }
   }
 
@@ -1424,6 +1451,10 @@
             _needExtensionTypeDeclaration(), Nullability.nonNullable);
       case DartTypeKind.VoidType:
         return VoidType();
+      case DartTypeKind.FunctionTypeParameterType:
+        throw new UnimplementedError("Unimplemented support for $kind.");
+      case DartTypeKind.ClassTypeParameterType:
+        throw new UnimplementedError("Unimplemented support for $kind.");
     }
   }
 
@@ -1815,6 +1846,15 @@
             _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
             _createExpression())
           ..fileOffset = _needFileOffset();
+      case NodeKind.LocalVariable:
+      case NodeKind.PositionalParameter:
+      case NodeKind.NamedParameter:
+      case NodeKind.SyntheticVariable:
+      case NodeKind.ThisVariable:
+      case NodeKind.TypeVariable:
+      case NodeKind.Scope:
+      case NodeKind.VariableContext:
+        throw new UnimplementedError("Unimplemented support for kind $kind.");
     }
   }
 
diff --git a/pkg/kernel/lib/src/non_null.dart b/pkg/kernel/lib/src/non_null.dart
index 48308b7..6079046 100644
--- a/pkg/kernel/lib/src/non_null.dart
+++ b/pkg/kernel/lib/src/non_null.dart
@@ -239,4 +239,18 @@
     // NonNull(void) = void
     return null;
   }
+
+  @override
+  DartType? visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType? visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart
index 16f2479..579f6a5 100644
--- a/pkg/kernel/lib/src/printer.dart
+++ b/pkg/kernel/lib/src/printer.dart
@@ -97,7 +97,8 @@
   int _constantLevel = 0;
   int _indentationLevel = 0;
   late final Map<LabeledStatement, String> _labelNames = {};
-  late final Map<VariableDeclaration, String> _variableNames = {};
+  late final Map<VariableDeclaration, String> _variableDeclarationNames = {};
+  late final Map<Variable, String> _variableNames = {};
 
   AstPrinter(this._strategy);
 
@@ -202,12 +203,29 @@
     return _labelNames[node] ??= 'label${_labelNames.length}';
   }
 
-  String getVariableName(VariableDeclaration node) {
+  String getVariableDeclarationName(VariableDeclaration node) {
     String? name = node.name;
     if (name != null) {
       return name;
     }
-    return _variableNames[node] ??= '#${_variableNames.length}';
+    return _variableDeclarationNames[node] ??=
+        '#${_variableDeclarationNames.length}';
+  }
+
+  String getVariableName(Variable node) {
+    switch (node) {
+      case NamedParameter(:var name):
+      case PositionalParameter(cosmeticName: var name?):
+      case TypeVariable(cosmeticName: var name?):
+        return name;
+      case ThisVariable():
+        return 'this';
+      case PositionalParameter(cosmeticName: null):
+      case TypeVariable(cosmeticName: null):
+      case SyntheticVariable():
+      case LocalVariable():
+        return _variableNames[node] ??= '#${_variableNames.length}';
+    }
   }
 
   String getSwitchCaseName(SwitchCase node) {
@@ -479,7 +497,7 @@
       writeType(type ?? node.type);
       _sb.write(' ');
     }
-    _sb.write(getVariableName(node));
+    _sb.write(getVariableDeclarationName(node));
     if (includeInitializer && node.initializer != null && !node.isRequired) {
       _sb.write(' = ');
       writeExpression(node.initializer!);
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index abdcd83..9d79b43 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -362,4 +362,20 @@
     // [AuxiliaryType]s.
     return null;
   }
+
+  @override
+  DartType? visitFunctionTypeParameterType(
+      FunctionTypeParameterType node, Variance arg) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType? visitClassTypeParameterType(
+      ClassTypeParameterType node, Variance arg) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 98dc7c9..8aa8496 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -131,6 +131,8 @@
       case (InvalidType(), _):
       case (_, InvalidType()):
       case (AuxiliaryType(), _):
+      case (FunctionTypeParameterType(), _):
+      case (ClassTypeParameterType(), _):
         throw new UnsupportedError("moretop($s, $t)");
     }
   }
@@ -234,6 +236,8 @@
       case (InvalidType(), _):
       case (_, InvalidType()):
       case (AuxiliaryType(), _):
+      case (FunctionTypeParameterType(), _):
+      case (ClassTypeParameterType(), _):
         throw new UnsupportedError("morebottom($s, $t)");
     }
   }
@@ -520,6 +524,20 @@
             "getStandardUpperBoundInternal("
             "${type1.runtimeType}, ${type2.runtimeType}"
             ")");
+
+      case (FunctionTypeParameterType(), _):
+      case (_, FunctionTypeParameterType()):
+        throw new StateError("Unimplemented for type combination: "
+            "getStandardUpperBoundInternal("
+            "${type1.runtimeType}, ${type2.runtimeType}"
+            ")");
+
+      case (ClassTypeParameterType(), _):
+      case (_, ClassTypeParameterType()):
+        throw new StateError("Unimplemented for type combination: "
+            "getStandardUpperBoundInternal("
+            "${type1.runtimeType}, ${type2.runtimeType}"
+            ")");
     }
   }
 
@@ -842,6 +860,20 @@
             "getStandardUpperBoundInternal("
             "${type1.runtimeType}, ${type2.runtimeType}"
             ")");
+
+      case (FunctionTypeParameterType(), _):
+      case (_, FunctionTypeParameterType()):
+        throw new StateError("Unimplemented for type combination: "
+            "getStandardUpperBoundInternal("
+            "${type1.runtimeType}, ${type2.runtimeType}"
+            ")");
+
+      case (ClassTypeParameterType(), _):
+      case (_, ClassTypeParameterType()):
+        throw new StateError("Unimplemented for type combination: "
+            "getStandardUpperBoundInternal("
+            "${type1.runtimeType}, ${type2.runtimeType}"
+            ")");
     }
   }
 
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index bc417a2..bbd7e53 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -1294,7 +1294,18 @@
 
       case (AuxiliaryType(), _):
       case (_, AuxiliaryType()):
-        throw "Unhandled type: ${t.runtimeType}";
+        throw "Unhandled type combination: "
+            "${s.runtimeType} ${t.runtimeType}";
+
+      case (FunctionTypeParameterType(), _):
+      case (_, FunctionTypeParameterType()):
+        throw "Unimplemented type combination: "
+            "${s.runtimeType} ${t.runtimeType}";
+
+      case (ClassTypeParameterType(), _):
+      case (_, ClassTypeParameterType()):
+        throw "Unimplemented type combination: "
+            "${s.runtimeType} ${t.runtimeType}";
     }
   }
 
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 0207788..ddc7d87 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -3300,6 +3300,12 @@
 
   @override
   int visitPatternAssignment(PatternAssignment node) => EXPRESSION;
+
+  @override
+  int visitVariableRead(VariableRead node) => PRIMARY;
+
+  @override
+  int visitVariableWrite(VariableWrite node) => EXPRESSION;
 }
 
 String procedureKindToString(ProcedureKind kind) {
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index eb4fc96..727ab2f 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -639,6 +639,20 @@
     node.left.accept(this);
     node.right.accept(this);
   }
+
+  @override
+  void visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  void visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
 
 class _NullSubstitution extends Substitution {
@@ -928,6 +942,20 @@
   DartType visitIntersectionType(IntersectionType node) {
     return node.left.accept(this);
   }
+
+  @override
+  DartType visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
 
 /// Combines nullabilities of types during type substitution.
@@ -1241,6 +1269,20 @@
   DartType visitIntersectionType(IntersectionType node) {
     return node.left.accept(this);
   }
+
+  @override
+  DartType visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
 
 class FunctionTypeInstantiator implements DartTypeVisitor<DartType?> {
@@ -1506,6 +1548,20 @@
     }
     return null;
   }
+
+  @override
+  DartType? visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType? visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
 
 class _OccurrenceVisitor extends FindTypeVisitor {
@@ -1639,6 +1695,16 @@
   }
 
   @override
+  bool visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    return false;
+  }
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node) {
+    return false;
+  }
+
+  @override
   bool visitStructuralParameterType(StructuralParameterType node) {
     return variables.contains(node.parameter);
   }
@@ -1790,6 +1856,12 @@
   bool visitTypeParameterType(TypeParameterType node) => true;
 
   @override
+  bool visitFunctionTypeParameterType(FunctionTypeParameterType node) => true;
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node) => true;
+
+  @override
   bool visitStructuralParameterType(StructuralParameterType node) {
     return true;
   }
@@ -1873,6 +1945,20 @@
   }
 
   @override
+  DartType visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
   DartType visitStructuralParameterType(StructuralParameterType node) {
     return node
         .withDeclaredNullability(node.parameter.computeNullabilityFromBound());
@@ -2200,6 +2286,20 @@
 
   @override
   bool visitVoidType(VoidType node) => false;
+
+  @override
+  bool visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
 
 /// Returns true if [type] is an application of the nullable type constructor.
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 4cebf26..e0898eb 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -1345,4 +1345,25 @@
   void visitPatternVariableDeclaration(PatternVariableDeclaration node) {
     // TODO(johnniwinther): Implement this.
   }
+
+  @override
+  void visitVariableInitialization(VariableInitialization node) {
+    // TODO(cstefantsova): Implement visitVariableInitialization.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitVariableRead(VariableRead node) {
+    // TODO(cstefantsova): Implement visitVariableRead.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  DartType visitVariableWrite(VariableWrite node) {
+    // TODO(cstefantsova): Implement visitVariableWrite.
+    throw UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index be9f8be..4e784b3 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -1925,4 +1925,18 @@
 
   @override
   bool visitVoidType(VoidType node) => true;
+
+  @override
+  bool visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitFunctionTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
+
+  @override
+  bool visitClassTypeParameterType(ClassTypeParameterType node) {
+    // TODO(cstefantsova): Implement visitClassTypeParameterType.
+    throw new UnimplementedError(
+        "Unimplemented support for $node (${node.runtimeType}).");
+  }
 }
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index d5cccf3..d0f62f6 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -80,6 +80,8 @@
   R visitRecordNameGet(RecordNameGet node);
   R visitSwitchExpression(SwitchExpression node);
   R visitPatternAssignment(PatternAssignment node);
+  R visitVariableRead(VariableRead node);
+  R visitVariableWrite(VariableWrite node);
 }
 
 /// Helper mixin for [ExpressionVisitor] that implements visit methods by
@@ -238,6 +240,10 @@
   R visitSwitchExpression(SwitchExpression node) => defaultExpression(node);
   @override
   R visitPatternAssignment(PatternAssignment node) => defaultExpression(node);
+  @override
+  R visitVariableRead(VariableRead node) => defaultExpression(node);
+  @override
+  R visitVariableWrite(VariableWrite node) => defaultExpression(node);
 }
 
 abstract class PatternVisitor<R> {
@@ -312,6 +318,7 @@
   R visitEmptyStatement(EmptyStatement node);
   R visitAssertStatement(AssertStatement node);
   R visitLabeledStatement(LabeledStatement node);
+  R visitVariableInitialization(VariableInitialization node);
   R visitBreakStatement(BreakStatement node);
   R visitWhileStatement(WhileStatement node);
   R visitDoStatement(DoStatement node);
@@ -352,6 +359,9 @@
   @override
   R visitLabeledStatement(LabeledStatement node) => defaultStatement(node);
   @override
+  R visitVariableInitialization(VariableInitialization node) =>
+      defaultStatement(node);
+  @override
   R visitBreakStatement(BreakStatement node) => defaultStatement(node);
   @override
   R visitWhileStatement(WhileStatement node) => defaultStatement(node);
@@ -544,6 +554,14 @@
   R visitMapPatternRestEntry(MapPatternRestEntry node);
   R visitPatternGuard(PatternGuard node);
   R visitComponent(Component node);
+  R visitTypeVariable(TypeVariable node);
+  R visitLocalVariable(LocalVariable node);
+  R visitPositionalParameter(PositionalParameter node);
+  R visitNamedParameter(NamedParameter node);
+  R visitThisVariable(ThisVariable node);
+  R visitSyntheticVariable(SyntheticVariable node);
+  R visitVariableContext(VariableContext node);
+  R visitScope(Scope node);
 }
 
 /// Helper mixin for [TreeVisitor] that implements visit methods by delegating
@@ -598,6 +616,22 @@
   R visitPatternGuard(PatternGuard node) => defaultTreeNode(node);
   @override
   R visitComponent(Component node) => defaultTreeNode(node);
+  @override
+  R visitTypeVariable(TypeVariable node) => defaultTreeNode(node);
+  @override
+  R visitLocalVariable(LocalVariable node) => defaultTreeNode(node);
+  @override
+  R visitPositionalParameter(PositionalParameter node) => defaultTreeNode(node);
+  @override
+  R visitNamedParameter(NamedParameter node) => defaultTreeNode(node);
+  @override
+  R visitThisVariable(ThisVariable node) => defaultTreeNode(node);
+  @override
+  R visitSyntheticVariable(SyntheticVariable node) => defaultTreeNode(node);
+  @override
+  R visitVariableContext(VariableContext node) => defaultTreeNode(node);
+  @override
+  R visitScope(Scope node) => defaultTreeNode(node);
 }
 
 /// Base class for implementing [TreeVisitor1] that implements visit methods
@@ -659,6 +693,14 @@
   R visitMapPatternRestEntry(MapPatternRestEntry node, A arg);
   R visitPatternGuard(PatternGuard node, A arg);
   R visitComponent(Component node, A arg);
+  R visitTypeVariable(TypeVariable node, A arg);
+  R visitLocalVariable(LocalVariable node, A arg);
+  R visitPositionalParameter(PositionalParameter node, A arg);
+  R visitNamedParameter(NamedParameter node, A arg);
+  R visitThisVariable(ThisVariable node, A arg);
+  R visitSyntheticVariable(SyntheticVariable node, A arg);
+  R visitVariableContext(VariableContext node, A arg);
+  R visitScope(Scope node, A arg);
 }
 
 /// Helper mixin for [TreeVisitor1] that implements visit methods by delegating
@@ -719,6 +761,26 @@
   R visitPatternGuard(PatternGuard node, A arg) => defaultTreeNode(node, arg);
   @override
   R visitComponent(Component node, A arg) => defaultTreeNode(node, arg);
+  @override
+  R visitTypeVariable(TypeVariable node, A arg) => defaultTreeNode(node, arg);
+  @override
+  R visitLocalVariable(LocalVariable node, A arg) => defaultTreeNode(node, arg);
+  @override
+  R visitPositionalParameter(PositionalParameter node, A arg) =>
+      defaultTreeNode(node, arg);
+  @override
+  R visitNamedParameter(NamedParameter node, A arg) =>
+      defaultTreeNode(node, arg);
+  @override
+  R visitThisVariable(ThisVariable node, A arg) => defaultTreeNode(node, arg);
+  @override
+  R visitSyntheticVariable(SyntheticVariable node, A arg) =>
+      defaultTreeNode(node, arg);
+  @override
+  R visitVariableContext(VariableContext node, A arg) =>
+      defaultTreeNode(node, arg);
+  @override
+  R visitScope(Scope node, A arg) => defaultTreeNode(node, arg);
 }
 
 /// Base class for implementing [TreeVisitor1] that implements visit methods
@@ -768,6 +830,8 @@
   R visitExtensionType(ExtensionType node);
   R visitIntersectionType(IntersectionType node);
   R visitRecordType(RecordType node);
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node);
+  R visitClassTypeParameterType(ClassTypeParameterType node);
 }
 
 /// Helper mixin for [DartTypeVisitor] that implements visit methods by
@@ -806,6 +870,12 @@
   R visitIntersectionType(IntersectionType node) => defaultDartType(node);
   @override
   R visitRecordType(RecordType node) => defaultDartType(node);
+  @override
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node) =>
+      defaultDartType(node);
+  @override
+  R visitClassTypeParameterType(ClassTypeParameterType node) =>
+      defaultDartType(node);
 }
 
 typedef DartTypeVisitor1AuxiliaryFunction<R, A> = R Function(
@@ -829,6 +899,8 @@
   R visitExtensionType(ExtensionType node, A arg);
   R visitIntersectionType(IntersectionType node, A arg);
   R visitRecordType(RecordType node, A arg);
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node, A arg);
+  R visitClassTypeParameterType(ClassTypeParameterType node, A arg);
 }
 
 /// Helper mixin for [DartTypeVisitor1] that implements visit methods by
@@ -869,6 +941,12 @@
       defaultDartType(node, arg);
   @override
   R visitRecordType(RecordType node, A arg) => defaultDartType(node, arg);
+  @override
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node, A arg) =>
+      defaultDartType(node, arg);
+  @override
+  R visitClassTypeParameterType(ClassTypeParameterType node, A arg) =>
+      defaultDartType(node, arg);
 }
 
 /// Visitor for [Constant] nodes.
@@ -2239,6 +2317,8 @@
   R visitRecordLiteral(RecordLiteral node, A arg);
   R visitSwitchExpression(SwitchExpression node, A arg);
   R visitPatternAssignment(PatternAssignment node, A arg);
+  R visitVariableRead(VariableRead node, A arg);
+  R visitVariableWrite(VariableWrite node, A arg);
 }
 
 /// Helper mixin for [ExpressionVisitor1] that implements visit methods by
@@ -2432,6 +2512,11 @@
   @override
   R visitPatternAssignment(PatternAssignment node, A arg) =>
       defaultExpression(node, arg);
+  @override
+  R visitVariableRead(VariableRead node, A arg) => defaultExpression(node, arg);
+  @override
+  R visitVariableWrite(VariableWrite node, A arg) =>
+      defaultExpression(node, arg);
 }
 
 abstract class PatternVisitor1<R, A> {
@@ -2512,6 +2597,7 @@
   R visitEmptyStatement(EmptyStatement node, A arg);
   R visitAssertStatement(AssertStatement node, A arg);
   R visitLabeledStatement(LabeledStatement node, A arg);
+  R visitVariableInitialization(VariableInitialization node, A arg);
   R visitBreakStatement(BreakStatement node, A arg);
   R visitWhileStatement(WhileStatement node, A arg);
   R visitDoStatement(DoStatement node, A arg);
@@ -2556,6 +2642,9 @@
   R visitLabeledStatement(LabeledStatement node, A arg) =>
       defaultStatement(node, arg);
   @override
+  R visitVariableInitialization(VariableInitialization node, A arg) =>
+      defaultStatement(node, arg);
+  @override
   R visitBreakStatement(BreakStatement node, A arg) =>
       defaultStatement(node, arg);
   @override
@@ -2609,8 +2698,21 @@
 /// The mixin provides implementations of the visit methods for the experimental
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
-mixin DartTypeVisitorExperimentExclusionMixin<R>
-    implements DartTypeVisitor<R> {}
+mixin DartTypeVisitorExperimentExclusionMixin<R> implements DartTypeVisitor<R> {
+  @override
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node) {
+    throw StateError(
+      "${runtimeType}.visitFunctionTypeParameterType isn't supported.",
+    );
+  }
+
+  @override
+  R visitClassTypeParameterType(ClassTypeParameterType node) {
+    throw StateError(
+      "${runtimeType}.visitClassTypeParameterType isn't supported.",
+    );
+  }
+}
 
 /// [DartTypeVisitor1ExperimentExclusionMixin] is intended to reduce the effects
 /// of CFE experiments on the backends.
@@ -2619,7 +2721,21 @@
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
 mixin DartTypeVisitor1ExperimentExclusionMixin<R, A>
-    implements DartTypeVisitor1<R, A> {}
+    implements DartTypeVisitor1<R, A> {
+  @override
+  R visitFunctionTypeParameterType(FunctionTypeParameterType node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitFunctionTypeParameterType isn't supported.",
+    );
+  }
+
+  @override
+  R visitClassTypeParameterType(ClassTypeParameterType node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitClassTypeParameterType isn't supported.",
+    );
+  }
+}
 
 /// [ExpressionVisitorExperimentExclusionMixin] is intended to reduce the
 /// effects of CFE experiments on the backends.
@@ -2628,7 +2744,21 @@
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
 mixin ExpressionVisitorExperimentExclusionMixin<R>
-    implements ExpressionVisitor<R> {}
+    implements ExpressionVisitor<R> {
+  @override
+  R visitVariableRead(VariableRead node) {
+    throw StateError(
+      "${runtimeType}.visitVariableRead isn't supported.",
+    );
+  }
+
+  @override
+  R visitVariableWrite(VariableWrite node) {
+    throw StateError(
+      "${runtimeType}.visitVariableWrite isn't supported.",
+    );
+  }
+}
 
 /// [ExpressionVisitor1ExperimentExclusionMixin] is intended to reduce the
 /// effects of CFE experiments on the backends.
@@ -2637,7 +2767,21 @@
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
 mixin ExpressionVisitor1ExperimentExclusionMixin<R, A>
-    implements ExpressionVisitor1<R, A> {}
+    implements ExpressionVisitor1<R, A> {
+  @override
+  R visitVariableRead(VariableRead node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitVariableRead isn't supported.",
+    );
+  }
+
+  @override
+  R visitVariableWrite(VariableWrite node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitVariableWrite isn't supported.",
+    );
+  }
+}
 
 /// [StatementVisitorExperimentExclusionMixin] is intended to reduce the effects
 /// of CFE experiments on the backends.
@@ -2646,7 +2790,14 @@
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
 mixin StatementVisitorExperimentExclusionMixin<R>
-    implements StatementVisitor<R> {}
+    implements StatementVisitor<R> {
+  @override
+  R visitVariableInitialization(VariableInitialization node) {
+    throw StateError(
+      "${runtimeType}.visitVariableInitialization isn't supported.",
+    );
+  }
+}
 
 /// [StatementVisitor1ExperimentExclusionMixin] is intended to reduce the
 /// effects of CFE experiments on the backends.
@@ -2655,7 +2806,14 @@
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
 mixin StatementVisitor1ExperimentExclusionMixin<R, A>
-    implements StatementVisitor1<R, A> {}
+    implements StatementVisitor1<R, A> {
+  @override
+  R visitVariableInitialization(VariableInitialization node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitVariableInitialization isn't supported.",
+    );
+  }
+}
 
 /// [TreeVisitorExperimentExclusionMixin] is intended to reduce the effects of
 /// CFE experiments on the backends.
@@ -2663,7 +2821,63 @@
 /// The mixin provides implementations of the visit methods for the experimental
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
-mixin TreeVisitorExperimentExclusionMixin<R> implements TreeVisitor<R> {}
+mixin TreeVisitorExperimentExclusionMixin<R> implements TreeVisitor<R> {
+  @override
+  R visitTypeVariable(TypeVariable node) {
+    throw StateError(
+      "${runtimeType}.visitTypeVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitLocalVariable(LocalVariable node) {
+    throw StateError(
+      "${runtimeType}.visitLocalVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitPositionalParameter(PositionalParameter node) {
+    throw StateError(
+      "${runtimeType}.visitPositionalParameter isn't supported.",
+    );
+  }
+
+  @override
+  R visitNamedParameter(NamedParameter node) {
+    throw StateError(
+      "${runtimeType}.visitNamedParameter isn't supported.",
+    );
+  }
+
+  @override
+  R visitThisVariable(ThisVariable node) {
+    throw StateError(
+      "${runtimeType}.visitThisVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitSyntheticVariable(SyntheticVariable node) {
+    throw StateError(
+      "${runtimeType}.visitSyntheticVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitVariableContext(VariableContext node) {
+    throw StateError(
+      "${runtimeType}.visitVariableContext isn't supported.",
+    );
+  }
+
+  @override
+  R visitScope(Scope node) {
+    throw StateError(
+      "${runtimeType}.visitScope isn't supported.",
+    );
+  }
+}
 
 /// [TreeVisitor1ExperimentExclusionMixin] is intended to reduce the effects of
 /// CFE experiments on the backends.
@@ -2671,5 +2885,60 @@
 /// The mixin provides implementations of the visit methods for the experimental
 /// nodes. The methods throw an exception signaling that the experimental nodes
 /// aren't supported.
-mixin TreeVisitor1ExperimentExclusionMixin<R, A>
-    implements TreeVisitor1<R, A> {}
+mixin TreeVisitor1ExperimentExclusionMixin<R, A> implements TreeVisitor1<R, A> {
+  @override
+  R visitTypeVariable(TypeVariable node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitTypeVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitLocalVariable(LocalVariable node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitLocalVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitPositionalParameter(PositionalParameter node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitPositionalParameter isn't supported.",
+    );
+  }
+
+  @override
+  R visitNamedParameter(NamedParameter node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitNamedParameter isn't supported.",
+    );
+  }
+
+  @override
+  R visitThisVariable(ThisVariable node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitThisVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitSyntheticVariable(SyntheticVariable node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitSyntheticVariable isn't supported.",
+    );
+  }
+
+  @override
+  R visitVariableContext(VariableContext node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitVariableContext isn't supported.",
+    );
+  }
+
+  @override
+  R visitScope(Scope node, A arg) {
+    throw StateError(
+      "${runtimeType}.visitScope isn't supported.",
+    );
+  }
+}