Switch flow analysis tests to performFlowAnalysis().

So, we can make visitors private.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I8ff98e95b30f4b2d807a7b3d2a63e125d9420669
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107180
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
index 838ae88..b148cda 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
@@ -375,12 +375,12 @@
     }
   }
 
-  /// Return `true` if the [variable] is known to be be nullable.
+  /// Return `true` if the [variable] is known to be be non-nullable.
   bool isNonNullable(Element variable) {
     return !_current.notNonNullable.contains(variable);
   }
 
-  /// Return `true` if the [variable] is known to be be non-nullable.
+  /// Return `true` if the [variable] is known to be be nullable.
   bool isNullable(Element variable) {
     return !_current.notNullable.contains(variable);
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index a95f526..bc05fe3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -17,35 +17,77 @@
   CompilationUnit unit,
 ) {
   var assignedVariables = AssignedVariables<Statement, VariableElement>();
-  unit.accept(AssignedVariablesVisitor(assignedVariables));
+  unit.accept(_AssignedVariablesVisitor(assignedVariables));
 
   var readBeforeWritten = <LocalVariableElement>[];
+  var nullableNodes = <SimpleIdentifier>[];
+  var nonNullableNodes = <SimpleIdentifier>[];
+  var unreachableNodes = <AstNode>[];
+  var functionBodiesThatDontComplete = <FunctionBody>[];
+  var promotedTypes = <SimpleIdentifier, DartType>{};
 
-  unit.accept(FlowAnalysisVisitor(
+  unit.accept(_FlowAnalysisVisitor(
     typeSystem,
     assignedVariables,
-    {},
+    promotedTypes,
     readBeforeWritten,
-    [],
-    [],
-    [],
-    [],
+    nullableNodes,
+    nonNullableNodes,
+    unreachableNodes,
+    functionBodiesThatDontComplete,
   ));
 
   return FlowAnalysisResult(
     readBeforeWritten,
+    nullableNodes,
+    nonNullableNodes,
+    unreachableNodes,
+    functionBodiesThatDontComplete,
+    promotedTypes,
+  );
+}
+
+/// The result of performing flow analysis on a unit.
+class FlowAnalysisResult {
+  final List<LocalVariableElement> readBeforeWritten;
+
+  /// The list of identifiers, resolved to a local variable or a parameter,
+  /// where the variable is known to be nullable.
+  final List<SimpleIdentifier> nullableNodes;
+
+  /// The list of identifiers, resolved to a local variable or a parameter,
+  /// where the variable is known to be non-nullable.
+  final List<SimpleIdentifier> nonNullableNodes;
+
+  /// The list of nodes, [Expression]s or [Statement]s, that cannot be reached,
+  /// for example because a previous statement always exits.
+  final List<AstNode> unreachableNodes;
+
+  /// The list of [FunctionBody]s that don't complete, for example because
+  /// there is a `return` statement at the end of the function body block.
+  final List<FunctionBody> functionBodiesThatDontComplete;
+
+  /// For each local variable or parameter, which type is promoted to a type
+  /// specific than its declaration type, this map included references where
+  /// the variable where it is read, and the type it has.
+  final Map<SimpleIdentifier, DartType> promotedTypes;
+
+  FlowAnalysisResult(
+    this.readBeforeWritten,
+    this.nullableNodes,
+    this.nonNullableNodes,
+    this.unreachableNodes,
+    this.functionBodiesThatDontComplete,
+    this.promotedTypes,
   );
 }
 
 /// The visitor that gathers local variables that are potentially assigned
 /// in corresponding statements, such as loops, `switch` and `try`.
-///
-/// TODO(scheglov) Change other tests to use [performFlowAnalysis],
-/// and make this class private.
-class AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
+class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
   final AssignedVariables assignedVariables;
 
-  AssignedVariablesVisitor(this.assignedVariables);
+  _AssignedVariablesVisitor(this.assignedVariables);
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
@@ -135,34 +177,24 @@
   }
 }
 
-/// The result of performing flow analysis on a unit.
-class FlowAnalysisResult {
-  final List<LocalVariableElement> readBeforeWritten;
-
-  FlowAnalysisResult(this.readBeforeWritten);
-}
-
 /// [AstVisitor] that drives the [FlowAnalysis].
-///
-/// TODO(scheglov) Change other tests to use [performFlowAnalysis],
-/// and make this class private.
-class FlowAnalysisVisitor extends GeneralizingAstVisitor<void> {
+class _FlowAnalysisVisitor extends GeneralizingAstVisitor<void> {
   static final trueLiteral = astFactory.booleanLiteral(null, true);
 
   final NodeOperations<Expression> nodeOperations;
   final TypeOperations<VariableElement, DartType> typeOperations;
   final AssignedVariables assignedVariables;
 
-  final Map<AstNode, DartType> promotedTypes;
+  final Map<SimpleIdentifier, DartType> promotedTypes;
   final List<LocalVariableElement> readBeforeWritten;
-  final List<AstNode> nullableNodes;
-  final List<AstNode> nonNullableNodes;
+  final List<SimpleIdentifier> nullableNodes;
+  final List<SimpleIdentifier> nonNullableNodes;
   final List<AstNode> unreachableNodes;
   final List<FunctionBody> functionBodiesThatDontComplete;
 
   FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
 
-  FlowAnalysisVisitor(
+  _FlowAnalysisVisitor(
       TypeSystem typeSystem,
       this.assignedVariables,
       this.promotedTypes,
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
index 19dc3b0..89142a2 100644
--- a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -3,9 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -23,7 +20,7 @@
 
 @reflectiveTest
 class DefiniteAssignmentFlowTest extends DriverResolutionTest {
-  final List<LocalVariableElement> readBeforeWritten = [];
+  FlowAnalysisResult flowResult;
 
   /// Assert that only local variables with the given names are marked as read
   /// before being written.  All the other local variables are implicitly
@@ -34,7 +31,7 @@
         .where((i) => i != null)
         .map((name) => findElement.localVar(name))
         .toList();
-    expect(readBeforeWritten, unorderedEquals(expected));
+    expect(flowResult.readBeforeWritten, unorderedEquals(expected));
   }
 
   test_assignment_leftExpression() async {
@@ -613,7 +610,7 @@
 }
 ''');
     var localV = findNode.simple('v; // 1').staticElement;
-    expect(readBeforeWritten, unorderedEquals([localV]));
+    expect(flowResult.readBeforeWritten, unorderedEquals([localV]));
   }
 
   test_functionExpression_localFunction_local2() async {
@@ -1306,15 +1303,13 @@
     var unit = result.unit;
     var typeSystem = result.typeSystem;
 
-    var flowAnalysisResult = performFlowAnalysis(typeSystem, unit);
-    readBeforeWritten.addAll(flowAnalysisResult.readBeforeWritten);
+    flowResult = performFlowAnalysis(typeSystem, unit);
   }
 }
 
 @reflectiveTest
 class NullableFlowTest extends DriverResolutionTest {
-  final List<AstNode> nullableNodes = [];
-  final List<AstNode> nonNullableNodes = [];
+  FlowAnalysisResult flowResult;
 
   void assertNonNullable([
     String search1,
@@ -1327,7 +1322,7 @@
         .where((i) => i != null)
         .map((search) => findNode.simple(search))
         .toList();
-    expect(nonNullableNodes, unorderedEquals(expected));
+    expect(flowResult.nonNullableNodes, unorderedEquals(expected));
   }
 
   void assertNullable([
@@ -1341,7 +1336,7 @@
         .where((i) => i != null)
         .map((search) => findNode.simple(search))
         .toList();
-    expect(nullableNodes, unorderedEquals(expected));
+    expect(flowResult.nullableNodes, unorderedEquals(expected));
   }
 
   test_assign_toNonNull() async {
@@ -1608,28 +1603,15 @@
     await resolveTestFile();
 
     var unit = result.unit;
+    var typeSystem = result.typeSystem;
 
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(FlowAnalysisVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      [],
-      nullableNodes,
-      nonNullableNodes,
-      [],
-      [],
-    ));
+    flowResult = performFlowAnalysis(typeSystem, unit);
   }
 }
 
 @reflectiveTest
 class ReachableFlowTest extends DriverResolutionTest {
-  final List<AstNode> unreachableNodes = [];
-  final List<FunctionBody> functionBodiesThatDontComplete = [];
+  FlowAnalysisResult flowResult;
 
   test_conditional_false() async {
     await trackCode(r'''
@@ -2055,21 +2037,9 @@
     await resolveTestFile();
 
     var unit = result.unit;
+    var typeSystem = result.typeSystem;
 
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(FlowAnalysisVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      [],
-      [],
-      [],
-      unreachableNodes,
-      functionBodiesThatDontComplete,
-    ));
+    flowResult = performFlowAnalysis(typeSystem, unit);
   }
 
   void verify({
@@ -2086,11 +2056,11 @@
     );
 
     expect(
-      this.unreachableNodes,
+      flowResult.unreachableNodes,
       unorderedEquals(expectedUnreachableNodes),
     );
     expect(
-      this.functionBodiesThatDontComplete,
+      flowResult.functionBodiesThatDontComplete,
       unorderedEquals(
         functionBodiesThatDontComplete
             .map((search) => findNode.functionBody(search))
@@ -2102,17 +2072,17 @@
 
 @reflectiveTest
 class TypePromotionFlowTest extends DriverResolutionTest {
-  final Map<AstNode, DartType> promotedTypes = {};
+  FlowAnalysisResult flowResult;
 
   void assertNotPromoted(String search) {
     var node = findNode.simple(search);
-    var actualType = promotedTypes[node];
+    var actualType = flowResult.promotedTypes[node];
     expect(actualType, isNull, reason: search);
   }
 
   void assertPromoted(String search, String expectedType) {
     var node = findNode.simple(search);
-    var actualType = promotedTypes[node];
+    var actualType = flowResult.promotedTypes[node];
     if (actualType == null) {
       fail('$expectedType expected, but actually not promoted\n$search');
     }
@@ -2888,20 +2858,8 @@
     await resolveTestFile();
 
     var unit = result.unit;
+    var typeSystem = result.typeSystem;
 
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(FlowAnalysisVisitor(
-      typeSystem,
-      assignedVariables,
-      promotedTypes,
-      [],
-      [],
-      [],
-      [],
-      [],
-    ));
+    flowResult = performFlowAnalysis(typeSystem, unit);
   }
 }