Version 2.17.0-50.0.dev

Merge commit 'f26ae5aede37eaf472460813f53aed5a9f288a4c' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
index 481ceb7..625037b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
@@ -120,8 +120,8 @@
     _inferArgumentTypes(node);
     _resolver.visitArgumentList(node.argumentList,
         whyNotPromotedList: whyNotPromotedList);
-    node.accept(_resolver.elementResolver);
-    node.accept(_resolver.typeAnalyzer);
+    _resolver.elementResolver.visitInstanceCreationExpression(node);
+    _resolver.typeAnalyzer.visitInstanceCreationExpression(node);
     _resolver.checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedList);
   }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 2dc6017..b32cea7 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
@@ -74,7 +73,7 @@
 /// undeclared variables (which is an error) and names in hide and show
 /// combinators that are not defined in the imported library (which is not an
 /// error).
-class ElementResolver extends SimpleAstVisitor<void> {
+class ElementResolver {
   /// The resolver driving this participant.
   final ResolverVisitor _resolver;
 
@@ -112,24 +111,19 @@
 
   TypeProviderImpl get _typeProvider => _resolver.typeProvider;
 
-  @override
   void visitClassDeclaration(ClassDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitClassTypeAlias(ClassTypeAlias node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitCommentReference(CommentReference node) {
     _commentReferenceResolver.resolve(node);
   }
 
-  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    super.visitConstructorDeclaration(node);
     ConstructorElement element = node.declaredElement!;
     if (element is ConstructorElementImpl) {
       var redirectedNode = node.redirectedConstructor;
@@ -150,7 +144,6 @@
     }
   }
 
-  @override
   void visitConstructorFieldInitializer(
       covariant ConstructorFieldInitializerImpl node) {
     var fieldName = node.fieldName;
@@ -159,7 +152,6 @@
     fieldName.staticElement = fieldElement;
   }
 
-  @override
   void visitConstructorName(covariant ConstructorNameImpl node) {
     var type = node.type2.type;
     if (type == null) {
@@ -183,22 +175,18 @@
     }
   }
 
-  @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitEnumDeclaration(EnumDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitExportDirective(ExportDirective node) {
     var exportElement = node.element;
     if (exportElement != null) {
@@ -210,43 +198,34 @@
     }
   }
 
-  @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     _resolveMetadataForParameter(node);
-    super.visitFieldFormalParameter(node);
   }
 
-  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     _resolveMetadataForParameter(node);
   }
 
-  @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitImportDirective(covariant ImportDirectiveImpl node) {
     var prefixNode = node.prefix;
     if (prefixNode != null) {
@@ -272,7 +251,6 @@
     }
   }
 
-  @override
   void visitInstanceCreationExpression(
       covariant InstanceCreationExpressionImpl node) {
     var invokedConstructor = node.constructorName.staticElement;
@@ -284,17 +262,14 @@
     }
   }
 
-  @override
   void visitLibraryDirective(LibraryDirective node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitMethodInvocation(MethodInvocation node,
       {List<WhyNotPromotedGetter>? whyNotPromotedList}) {
     whyNotPromotedList ??= [];
@@ -302,22 +277,18 @@
         node as MethodInvocationImpl, whyNotPromotedList);
   }
 
-  @override
   void visitMixinDeclaration(MixinDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitPartDirective(PartDirective node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitPartOfDirective(PartOfDirective node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitRedirectingConstructorInvocation(
       covariant RedirectingConstructorInvocationImpl node) {
     var enclosingClass = _resolver.enclosingClass;
@@ -348,12 +319,10 @@
     }
   }
 
-  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     _resolveMetadataForParameter(node);
   }
 
-  @override
   void visitSuperConstructorInvocation(
       covariant SuperConstructorInvocationImpl node) {
     var enclosingClass = _resolver.enclosingClass;
@@ -416,7 +385,6 @@
     }
   }
 
-  @override
   void visitSuperExpression(SuperExpression node) {
     var context = SuperContext.of(node);
     if (context == SuperContext.annotation || context == SuperContext.static) {
@@ -426,20 +394,16 @@
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.SUPER_IN_EXTENSION, node);
     }
-    super.visitSuperExpression(node);
   }
 
-  @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitTypeParameter(TypeParameter node) {
     _resolveAnnotations(node.metadata);
   }
 
-  @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
     _resolveAnnotations(node.metadata);
   }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index ee635b2..ad8e1da 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -161,10 +161,10 @@
   }
 }
 
-/// Base class for visitors that perform resolution.  This class keeps track of
-/// some of the basic information that is needed by resolution stages, such as
-/// the defining library and the error reporter.
-abstract class ResolverBase extends UnifyingAstVisitor<void> {
+/// Instances of the class `ResolverVisitor` are used to resolve the nodes
+/// within a single compilation unit.
+class ResolverVisitor extends ThrowingAstVisitor<void>
+    with ErrorDetectionHelpers {
   /// The element for the library containing the compilation unit being visited.
   final LibraryElementImpl definingLibrary;
 
@@ -174,22 +174,9 @@
   /// The object used to access the types from the core library.
   final TypeProviderImpl typeProvider;
 
-  /// The error reporter that will be informed of any errors that are found
-  /// during resolution.
+  @override
   final ErrorReporter errorReporter;
 
-  ResolverBase(this.definingLibrary, this.source, this.typeProvider,
-      AnalysisErrorListener errorListener)
-      : errorReporter = ErrorReporter(
-          errorListener,
-          source,
-          isNonNullableByDefault: definingLibrary.isNonNullableByDefault,
-        );
-}
-
-/// Instances of the class `ResolverVisitor` are used to resolve the nodes
-/// within a single compilation unit.
-class ResolverVisitor extends ResolverBase with ErrorDetectionHelpers {
   /// The class containing the AST nodes being visited,
   /// or `null` if we are not in the scope of a class.
   ClassElement? enclosingClass;
@@ -326,7 +313,7 @@
             definingLibrary,
             source,
             definingLibrary.typeSystem,
-            typeProvider,
+            typeProvider as TypeProviderImpl,
             errorListener,
             featureSet ??
                 definingLibrary.context.analysisOptions.contextFeatures,
@@ -336,19 +323,22 @@
 
   ResolverVisitor._(
       this.inheritance,
-      LibraryElementImpl definingLibrary,
-      Source source,
+      this.definingLibrary,
+      this.source,
       this.typeSystem,
-      TypeProvider typeProvider,
+      this.typeProvider,
       AnalysisErrorListener errorListener,
       FeatureSet featureSet,
       this.flowAnalysis,
       this._migratableAstInfoProvider,
       MigrationResolutionHooks? migrationResolutionHooks)
-      : _featureSet = featureSet,
-        migrationResolutionHooks = migrationResolutionHooks,
-        super(definingLibrary, source, typeProvider as TypeProviderImpl,
-            errorListener) {
+      : errorReporter = ErrorReporter(
+          errorListener,
+          source,
+          isNonNullableByDefault: definingLibrary.isNonNullableByDefault,
+        ),
+        _featureSet = featureSet,
+        migrationResolutionHooks = migrationResolutionHooks {
     var analysisOptions =
         definingLibrary.context.analysisOptions as AnalysisOptionsImpl;
 
@@ -1069,6 +1059,13 @@
   }
 
   @override
+  void visitAdjacentStrings(AdjacentStrings node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitAdjacentStrings(node as AdjacentStringsImpl);
+  }
+
+  @override
   void visitAnnotation(covariant AnnotationImpl node) {
     var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     _annotationResolver.resolve(node, whyNotPromotedList);
@@ -1154,13 +1151,13 @@
       flow?.equalityOp_end(
           node.parent as Expression, secondArg, secondArg.typeOrThrow);
     }
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
   }
 
   @override
   void visitAsExpression(AsExpression node) {
-    super.visitAsExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitAsExpression(node as AsExpressionImpl);
     flowAnalysis.asExpression(node);
     insertGenericFunctionInstantiation(node);
   }
@@ -1208,7 +1205,9 @@
       var futureUnion = _createFutureOr(contextType);
       InferenceContext.setType(node.expression, futureUnion);
     }
-    super.visitAwaitExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitAwaitExpression(node as AwaitExpressionImpl);
     insertGenericFunctionInstantiation(node);
   }
 
@@ -1224,11 +1223,18 @@
   }
 
   @override
+  void visitBlock(Block node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitBlockFunctionBody(BlockFunctionBody node) {
     try {
       inferenceContext.pushFunctionBodyContext(node);
       _thisAccessTracker.enterFunctionBody(node);
-      super.visitBlockFunctionBody(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
     } finally {
       _thisAccessTracker.exitFunctionBody(node);
       inferenceContext.popFunctionBodyContext(node);
@@ -1238,7 +1244,9 @@
   @override
   void visitBooleanLiteral(BooleanLiteral node) {
     flowAnalysis.flow?.booleanLiteral(node, node.value);
-    super.visitBooleanLiteral(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitBooleanLiteral(node as BooleanLiteralImpl);
   }
 
   @override
@@ -1248,8 +1256,6 @@
     // of the statement.
     //
     checkUnreachableNode(node);
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
     flowAnalysis.breakStatement(node);
   }
 
@@ -1266,13 +1272,18 @@
 
     node.cascadeSections.accept(this);
 
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+    typeAnalyzer.visitCascadeExpression(node);
 
     nullShortingTermination(node);
   }
 
   @override
+  void visitCatchClause(CatchClause node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitClassDeclaration(ClassDeclaration node) {
     //
     // Continue the class resolution.
@@ -1280,9 +1291,9 @@
     var outerType = enclosingClass;
     try {
       enclosingClass = node.declaredElement;
-      super.visitClassDeclaration(node);
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitClassDeclaration(node);
     } finally {
       enclosingClass = outerType;
     }
@@ -1290,10 +1301,15 @@
 
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
-    super.visitClassTypeAlias(node);
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitClassTypeAlias.
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitClassTypeAlias(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
@@ -1302,8 +1318,7 @@
     // We do not visit the expression because it needs to be visited in the
     // context of the reference.
     //
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+    elementResolver.visitCommentReference(node);
   }
 
   @override
@@ -1318,8 +1333,6 @@
     for (int i = 0; i < declarationCount; i++) {
       declarations[i].accept(this);
     }
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
   }
 
   @override
@@ -1358,8 +1371,7 @@
     }
     elseExpression = node.elseExpression;
 
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+    typeAnalyzer.visitConditionalExpression(node as ConditionalExpressionImpl);
   }
 
   @override
@@ -1381,7 +1393,9 @@
       _enclosingFunction = node.declaredElement;
       assert(_thisType == null);
       _setupThisType();
-      super.visitConstructorDeclaration(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitConstructorDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
       _thisType = null;
@@ -1411,8 +1425,8 @@
     expression.accept(this);
     expression = node.expression;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(expression);
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+    elementResolver.visitConstructorFieldInitializer(
+        node as ConstructorFieldInitializerImpl);
     if (fieldElement != null) {
       if (fieldType != null && expression.staticType != null) {
         var callReference = insertImplicitCallReference(expression);
@@ -1431,7 +1445,7 @@
   @override
   void visitConstructorName(ConstructorName node) {
     node.type2.accept(this);
-    node.accept(elementResolver);
+    elementResolver.visitConstructorName(node as ConstructorNameImpl);
   }
 
   @override
@@ -1440,21 +1454,33 @@
   }
 
   @override
+  void visitConstructorSelector(ConstructorSelector node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitContinueStatement(ContinueStatement node) {
     //
     // We do not visit the label because it needs to be visited in the context
     // of the statement.
     //
     checkUnreachableNode(node);
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
     flowAnalysis.continueStatement(node);
   }
 
   @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitDeclaredIdentifier(node);
+  }
+
+  @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     InferenceContext.setType(node.defaultValue, node.declaredElement?.type);
-    super.visitDefaultFormalParameter(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
     ParameterElement element = node.declaredElement!;
 
     if (element is DefaultParameterElementImpl && node.isOfLocalFunction) {
@@ -1483,17 +1509,39 @@
   }
 
   @override
+  void visitDoubleLiteral(DoubleLiteral node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitDoubleLiteral(node as DoubleLiteralImpl);
+  }
+
+  @override
   void visitEmptyFunctionBody(EmptyFunctionBody node) {
     if (resolveOnlyCommentInFunctionBody) {
       return;
     }
-    super.visitEmptyFunctionBody(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitEnumConstantArguments(EnumConstantArguments node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     node.metadata.accept(this);
-    super.visitEnumConstantDeclaration(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitEnumConstantDeclaration(node);
   }
 
   @override
@@ -1504,15 +1552,22 @@
     var outerType = enclosingClass;
     try {
       enclosingClass = node.declaredElement;
-      super.visitEnumDeclaration(node);
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitEnumDeclaration(node);
     } finally {
       enclosingClass = outerType;
     }
   }
 
   @override
+  void visitExportDirective(ExportDirective node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitExportDirective(node);
+  }
+
+  @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
     if (resolveOnlyCommentInFunctionBody) {
       return;
@@ -1526,7 +1581,8 @@
       );
       _thisAccessTracker.enterFunctionBody(node);
 
-      super.visitExpressionFunctionBody(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
       insertImplicitCallReference(node.expression);
 
       flowAnalysis.flow?.handleExit();
@@ -1539,13 +1595,25 @@
   }
 
   @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     var outerExtension = enclosingExtension;
     try {
       enclosingExtension = node.declaredElement!;
-      super.visitExtensionDeclaration(node);
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitExtensionDeclaration(node);
     } finally {
       enclosingExtension = outerExtension;
     }
@@ -1561,7 +1629,6 @@
     visitArgumentList(node.argumentList,
         whyNotPromotedList: whyNotPromotedList);
 
-    node.accept(elementResolver);
     extensionResolver.resolveOverride(node, whyNotPromotedList);
   }
 
@@ -1571,7 +1638,9 @@
     try {
       assert(_thisType == null);
       _setupThisType();
-      super.visitFieldDeclaration(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitFieldDeclaration(node);
     } finally {
       _thisAccessTracker.exitFieldDeclaration(node);
       _thisType = null;
@@ -1579,11 +1648,24 @@
   }
 
   @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitFieldFormalParameter(node);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     _forResolver.resolveElement(node as ForElementImpl);
   }
 
   @override
+  void visitFormalParameterList(FormalParameterList node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     _forResolver.resolveStatement(node as ForStatementImpl);
     nullSafetyDeadCodeVerifier.flowEnd(node.body);
@@ -1611,7 +1693,9 @@
     var outerFunction = _enclosingFunction;
     try {
       _enclosingFunction = node.declaredElement;
-      super.visitFunctionDeclaration(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitFunctionDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
     }
@@ -1632,10 +1716,12 @@
       flowAnalysis.topLevelDeclaration_exit();
     }
     nullSafetyDeadCodeVerifier.flowEnd(node);
+  }
 
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitFunctionDeclaration
+  @override
+  void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
@@ -1668,26 +1754,29 @@
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    super.visitFunctionTypeAlias(node);
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitFunctionTypeAlias.
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitFunctionTypeAlias(node);
   }
 
   @override
   void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    super.visitFunctionTypedFormalParameter(node);
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitFunctionTypedFormalParameter.
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitFunctionTypedFormalParameter(node);
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
-    super.visitGenericTypeAlias(node);
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitGenericTypeAlias.
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitGenericTypeAlias(node);
   }
 
   @override
@@ -1717,9 +1806,6 @@
     }
 
     flowAnalysis.flow?.ifStatement_end(elseElement != null);
-
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
   }
 
   @override
@@ -1749,9 +1835,25 @@
     }
 
     flowAnalysis.flow?.ifStatement_end(elseStatement != null);
+  }
 
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitImplicitCallReference(ImplicitCallReference node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitImportDirective(node as ImportDirectiveImpl);
   }
 
   @override
@@ -1799,8 +1901,29 @@
   }
 
   @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitIntegerLiteral(node);
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitInterpolationString(InterpolationString node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitIsExpression(IsExpression node) {
-    super.visitIsExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitIsExpression(node as IsExpressionImpl);
     flowAnalysis.isExpression(node);
   }
 
@@ -1810,11 +1933,19 @@
   @override
   void visitLabeledStatement(LabeledStatement node) {
     flowAnalysis.labeledStatement_enter(node);
-    super.visitLabeledStatement(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
     flowAnalysis.labeledStatement_exit(node);
   }
 
   @override
+  void visitLibraryDirective(LibraryDirective node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitLibraryDirective(node);
+  }
+
+  @override
   void visitLibraryIdentifier(LibraryIdentifier node) {}
 
   @override
@@ -1824,6 +1955,12 @@
   }
 
   @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     flowAnalysis.topLevelDeclaration_enter(node, node.parameters);
     flowAnalysis.executableDeclaration_enter(node, node.parameters, false);
@@ -1836,7 +1973,9 @@
       _enclosingFunction = node.declaredElement;
       assert(_thisType == null);
       _setupThisType();
-      super.visitMethodDeclaration(node);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitMethodDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
       _thisType = null;
@@ -1851,10 +1990,6 @@
     flowAnalysis.executableDeclaration_exit(node.body, false);
     flowAnalysis.topLevelDeclaration_exit();
     nullSafetyDeadCodeVerifier.flowEnd(node);
-
-    node.accept(elementResolver);
-    // Note: no need to call the typeAnalyzer since it does not override
-    // visitMethodDeclaration.
   }
 
   @override
@@ -1903,9 +2038,9 @@
     var outerType = enclosingClass;
     try {
       enclosingClass = node.declaredElement!;
-      super.visitMixinDeclaration(node);
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
+      checkUnreachableNode(node);
+      node.visitChildren(this);
+      elementResolver.visitMixinDeclaration(node);
     } finally {
       enclosingClass = outerType;
     }
@@ -1914,7 +2049,9 @@
   @override
   void visitNamedExpression(NamedExpression node) {
     InferenceContext.setTypeFromNode(node.expression, node);
-    super.visitNamedExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitNamedExpression(node as NamedExpressionImpl);
     // Any "why not promoted" information that flow analysis had associated with
     // `node.expression` now needs to be forwarded to `node`, so that when
     // `visitArgumentList` iterates through the arguments, it will find it.
@@ -1931,27 +2068,56 @@
   }
 
   @override
-  void visitNode(AstNode node) {
+  void visitNativeClause(NativeClause node) {
     checkUnreachableNode(node);
     node.visitChildren(this);
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+  }
+
+  @override
+  void visitNativeFunctionBody(NativeFunctionBody node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
   void visitNullLiteral(NullLiteral node) {
     flowAnalysis.flow?.nullLiteral(node);
-    super.visitNullLiteral(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitNullLiteral(node as NullLiteralImpl);
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     InferenceContext.setTypeFromNode(node.expression, node);
-    super.visitParenthesizedExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer
+        .visitParenthesizedExpression(node as ParenthesizedExpressionImpl);
     flowAnalysis.flow?.parenthesizedExpression(node, node.expression);
   }
 
   @override
+  void visitPartDirective(PartDirective node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitPartDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitPartOfDirective(node);
+  }
+
+  @override
   void visitPostfixExpression(PostfixExpression node) {
     _postfixExpressionResolver.resolve(node as PostfixExpressionImpl);
     insertGenericFunctionInstantiation(node);
@@ -2022,18 +2188,20 @@
     // invocation.
     //
     var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
-    node.accept(elementResolver);
+    elementResolver.visitRedirectingConstructorInvocation(
+        node as RedirectingConstructorInvocationImpl);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     visitArgumentList(node.argumentList,
         whyNotPromotedList: whyNotPromotedList);
-    node.accept(typeAnalyzer);
     checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedList);
   }
 
   @override
   void visitRethrowExpression(RethrowExpression node) {
-    super.visitRethrowExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitRethrowExpression(node as RethrowExpressionImpl);
     flowAnalysis.flow?.handleExit();
   }
 
@@ -2044,7 +2212,8 @@
       inferenceContext.bodyContext?.contextType,
     );
 
-    super.visitReturnStatement(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
 
     inferenceContext.bodyContext?.addReturnExpression(node.expression);
     flowAnalysis.flow?.handleExit();
@@ -2065,14 +2234,29 @@
   void visitShowCombinator(ShowCombinator node) {}
 
   @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitSimpleFormalParameter(node);
+  }
+
+  @override
   void visitSimpleIdentifier(covariant SimpleIdentifierImpl node) {
     _simpleIdentifierResolver.resolve(node);
     insertGenericFunctionInstantiation(node);
   }
 
   @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitSimpleStringLiteral(node as SimpleStringLiteralImpl);
+  }
+
+  @override
   void visitSpreadElement(SpreadElement node) {
-    super.visitSpreadElement(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
 
     if (!node.isNullAware) {
       nullableDereferenceVerifier.expression(
@@ -2083,6 +2267,13 @@
   }
 
   @override
+  void visitStringInterpolation(StringInterpolation node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitStringInterpolation(node as StringInterpolationImpl);
+  }
+
+  @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     //
     // We visit the argument list, but do not visit the optional identifier
@@ -2090,22 +2281,37 @@
     // invocation.
     //
     var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
-    node.accept(elementResolver);
+    elementResolver.visitSuperConstructorInvocation(
+        node as SuperConstructorInvocationImpl);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     visitArgumentList(node.argumentList,
         whyNotPromotedList: whyNotPromotedList);
-    node.accept(typeAnalyzer);
     checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedList);
   }
 
   @override
+  void visitSuperExpression(SuperExpression node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitSuperExpression(node);
+    typeAnalyzer.visitSuperExpression(node as SuperExpressionImpl);
+  }
+
+  @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitSwitchCase(SwitchCase node) {
     checkUnreachableNode(node);
 
     InferenceContext.setType(
         node.expression, _enclosingSwitchStatementExpressionType);
-    super.visitSwitchCase(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
 
     var flow = flowAnalysis.flow;
     if (flow != null && flow.isReachable && _isNonNullableByDefault) {
@@ -2123,7 +2329,8 @@
 
   @override
   void visitSwitchDefault(SwitchDefault node) {
-    super.visitSwitchDefault(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
     nullSafetyDeadCodeVerifier.flowEnd(node);
   }
 
@@ -2162,12 +2369,35 @@
   }
 
   @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitSymbolLiteral(node as SymbolLiteralImpl);
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitThisExpression(node as ThisExpressionImpl);
+  }
+
+  @override
   void visitThrowExpression(ThrowExpression node) {
-    super.visitThrowExpression(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    typeAnalyzer.visitThrowExpression(node as ThrowExpressionImpl);
     flowAnalysis.flow?.handleExit();
   }
 
   @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitTopLevelVariableDeclaration(node);
+  }
+
+  @override
   void visitTryStatement(TryStatement node) {
     checkUnreachableNode(node);
     var flow = flowAnalysis.flow!;
@@ -2215,6 +2445,31 @@
   }
 
   @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitTypeLiteral(TypeLiteral node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitTypeParameter(node);
+  }
+
+  @override
+  void visitTypeParameterList(TypeParameterList node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitVariableDeclaration(VariableDeclaration node) {
     _variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
 
@@ -2240,7 +2495,15 @@
       VariableElement variableElement = decl.declaredElement!;
       InferenceContext.setType(decl, variableElement.type);
     }
-    super.visitVariableDeclarationList(node);
+    checkUnreachableNode(node);
+    node.visitChildren(this);
+    elementResolver.visitVariableDeclarationList(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
@@ -2264,8 +2527,12 @@
     nullSafetyDeadCodeVerifier.flowEnd(node.body);
     // TODO(brianwilkerson) If the loop can only be exited because the condition
     // is false, then propagateFalseState(condition);
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    checkUnreachableNode(node);
+    node.visitChildren(this);
   }
 
   @override
@@ -2459,7 +2726,7 @@
             definingLibrary,
             source,
             typeSystem,
-            typeProvider,
+            typeProvider as TypeProviderImpl,
             errorListener,
             featureSet,
             FlowAnalysisHelperForMigration(
@@ -2514,9 +2781,22 @@
 ///
 /// TODO(paulberry): migrate the responsibility for all scope resolution into
 /// this visitor.
-class ScopeResolverVisitor extends ResolverBase {
+class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
   static const _nameScopeProperty = 'nameScope';
 
+  /// The element for the library containing the compilation unit being visited.
+  final LibraryElementImpl definingLibrary;
+
+  /// The source representing the compilation unit being visited.
+  final Source source;
+
+  /// The object used to access the types from the core library.
+  final TypeProviderImpl typeProvider;
+
+  /// The error reporter that will be informed of any errors that are found
+  /// during resolution.
+  final ErrorReporter errorReporter;
+
   /// The scope used to resolve identifiers.
   Scope nameScope;
 
@@ -2548,12 +2828,15 @@
   /// [nameScope] is the scope used to resolve identifiers in the node that will
   /// first be visited.  If `null` or unspecified, a new [LibraryScope] will be
   /// created based on [definingLibrary] and [typeProvider].
-  ScopeResolverVisitor(LibraryElementImpl definingLibrary, Source source,
-      TypeProvider typeProvider, AnalysisErrorListener errorListener,
+  ScopeResolverVisitor(this.definingLibrary, this.source, this.typeProvider,
+      AnalysisErrorListener errorListener,
       {Scope? nameScope})
-      : nameScope = nameScope ?? LibraryScope(definingLibrary),
-        super(definingLibrary, source, typeProvider as TypeProviderImpl,
-            errorListener);
+      : errorReporter = ErrorReporter(
+          errorListener,
+          source,
+          isNonNullableByDefault: definingLibrary.isNonNullableByDefault,
+        ),
+        nameScope = nameScope ?? LibraryScope(definingLibrary);
 
   /// Return the implicit label scope in which the current node is being
   /// resolved.
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 734711d..6bd3016 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
@@ -20,7 +19,7 @@
 /// * Every element that refers to types should be fully populated.
 /// * Every node representing an expression should be resolved to the Type of the expression.
 /// </ol>
-class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
+class StaticTypeAnalyzer {
   /// The resolver driving the resolution and type analysis.
   final ResolverVisitor _resolver;
 
@@ -48,7 +47,6 @@
 
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
-  @override
   void visitAdjacentStrings(covariant AdjacentStringsImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
@@ -59,7 +57,6 @@
   /// scope.
   ///
   /// The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
-  @override
   void visitAsExpression(covariant AsExpressionImpl node) {
     _inferenceHelper.recordStaticType(node, _getType(node.type));
   }
@@ -68,7 +65,6 @@
   ///
   ///   The static type of [the expression "await e"] is flatten(T) where T is
   ///   the static type of e.
-  @override
   void visitAwaitExpression(covariant AwaitExpressionImpl node) {
     var resultType = node.expression.typeOrThrow;
     resultType = _typeSystem.flatten(resultType);
@@ -77,7 +73,6 @@
 
   /// The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is
   /// bool.</blockquote>
-  @override
   void visitBooleanLiteral(covariant BooleanLiteralImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
@@ -85,7 +80,6 @@
   /// The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
   /// of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
   /// t;}(e)</i>.</blockquote>
-  @override
   void visitCascadeExpression(covariant CascadeExpressionImpl node) {
     _inferenceHelper.recordStaticType(node, node.target.typeOrThrow);
   }
@@ -97,19 +91,16 @@
   ///
   /// The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
   /// and the static type of <i>e<sub>3</sub></i>.</blockquote>
-  @override
   void visitConditionalExpression(covariant ConditionalExpressionImpl node) {
     _analyzeLeastUpperBound(node, node.thenExpression, node.elseExpression);
   }
 
   /// The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is
   /// double.</blockquote>
-  @override
   void visitDoubleLiteral(covariant DoubleLiteralImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.doubleType);
   }
 
-  @override
   void visitExtensionOverride(ExtensionOverride node) {
     assert(false,
         'Resolver should call extensionResolver.resolveOverride directly');
@@ -143,10 +134,8 @@
   /// x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic</i>. In any case
   /// where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
   /// specified as dynamic.</blockquote>
-  @override
   void visitFunctionExpression(FunctionExpression node) {}
 
-  @override
   void visitFunctionReference(covariant FunctionReferenceImpl node) {
     // TODO(paulberry): implement
     node.staticType = _dynamicType;
@@ -159,7 +148,6 @@
   /// The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
   /// expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
   /// form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
-  @override
   void visitInstanceCreationExpression(
       covariant InstanceCreationExpressionImpl node) {
     _inferInstanceCreationExpression(node);
@@ -182,7 +170,6 @@
   /// type of $e$ is the same as the static type of an integer literal with the
   /// same contexttype
   /// </blockquote>
-  @override
   void visitIntegerLiteral(IntegerLiteral node) {
     // Check the parent context for negated integer literals.
     var context = InferenceContext.getContext(
@@ -200,17 +187,14 @@
   /// denote a type available in the current lexical scope.
   ///
   /// The static type of an is-expression is `bool`.</blockquote>
-  @override
   void visitIsExpression(covariant IsExpressionImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
 
-  @override
   void visitMethodInvocation(MethodInvocation node) {
     throw StateError('Should not be invoked');
   }
 
-  @override
   void visitNamedExpression(covariant NamedExpressionImpl node) {
     Expression expression = node.expression;
     _inferenceHelper.recordStaticType(node, expression.typeOrThrow);
@@ -218,12 +202,10 @@
 
   /// The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
   /// </blockquote>
-  @override
   void visitNullLiteral(covariant NullLiteralImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.nullType);
   }
 
-  @override
   void visitParenthesizedExpression(
       covariant ParenthesizedExpressionImpl node) {
     Expression expression = node.expression;
@@ -232,26 +214,22 @@
 
   /// The Dart Language Specification, 12.9: <blockquote>The static type of a rethrow expression is
   /// bottom.</blockquote>
-  @override
   void visitRethrowExpression(covariant RethrowExpressionImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
   }
 
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
-  @override
   void visitSimpleStringLiteral(covariant SimpleStringLiteralImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
 
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
-  @override
   void visitStringInterpolation(covariant StringInterpolationImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
 
-  @override
   void visitSuperExpression(covariant SuperExpressionImpl node) {
     var thisType = _resolver.thisType;
     _resolver.flowAnalysis.flow?.thisOrSuper(node, thisType ?? _dynamicType);
@@ -265,14 +243,12 @@
     }
   }
 
-  @override
   void visitSymbolLiteral(covariant SymbolLiteralImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.symbolType);
   }
 
   /// The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
   /// interface of the immediately enclosing class.</blockquote>
-  @override
   void visitThisExpression(covariant ThisExpressionImpl node) {
     var thisType = _resolver.thisType;
     _resolver.flowAnalysis.flow?.thisOrSuper(node, thisType ?? _dynamicType);
@@ -287,7 +263,6 @@
 
   /// The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
   /// bottom.</blockquote>
-  @override
   void visitThrowExpression(covariant ThrowExpressionImpl node) {
     _inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
   }
diff --git a/tools/VERSION b/tools/VERSION
index 1c6615c..35fba8c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 49
+PRERELEASE 50
 PRERELEASE_PATCH 0
\ No newline at end of file