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);
}
}