Skip to content

Commit a5d6b81

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Use flow analysis to report potentially non-nullable local variables that are used before definitely assigned.
Not done yet: 1. Switching all unit tests to `performFlowAnalysis()`. 2. Updating the error code and renaming tests. 3. Writing more language_2/ tests. [email protected], [email protected] Change-Id: I0936f2daa4ab1cd91edeaca3eef9544eced5b443 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106982 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 8b523e8 commit a5d6b81

7 files changed

Lines changed: 862 additions & 734 deletions

File tree

pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import 'package:analyzer/src/dart/constant/utilities.dart';
2121
import 'package:analyzer/src/dart/element/element.dart';
2222
import 'package:analyzer/src/dart/element/handle.dart';
2323
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
24+
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
2425
import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
2526
import 'package:analyzer/src/error/codes.dart';
2627
import 'package:analyzer/src/error/inheritance_override.dart';
@@ -407,11 +408,17 @@ class LibraryAnalyzer {
407408
_context.typeSystem, _inheritance, errorReporter);
408409
inheritanceOverrideVerifier.verifyUnit(unit);
409410

411+
FlowAnalysisResult flowAnalysisResult;
412+
if (unit.featureSet.isEnabled(Feature.non_nullable)) {
413+
flowAnalysisResult = performFlowAnalysis(_context.typeSystem, unit);
414+
}
415+
410416
//
411417
// Use the ErrorVerifier to compute errors.
412418
//
413419
ErrorVerifier errorVerifier = new ErrorVerifier(
414-
errorReporter, _libraryElement, _typeProvider, _inheritance, false);
420+
errorReporter, _libraryElement, _typeProvider, _inheritance, false,
421+
flowAnalysisResult: flowAnalysisResult);
415422
unit.accept(errorVerifier);
416423
}
417424

pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
/// Sets of variables that are potentially assigned in a statement.
5+
/// Sets of local variables that are potentially assigned in a statement.
6+
///
7+
/// These statements are loops, `switch`, and `try` statements.
68
class AssignedVariables<Statement, Element> {
79
final emptySet = Set<Element>();
810

9-
/// Mapping from a [Statement] representing a loop to the set of variables
10-
/// that are potentially assigned in that loop.
11+
/// Mapping from a [Statement] to the set of local variables that are
12+
/// potentially assigned in that statement.
1113
final Map<Statement, Set<Element>> _map = {};
1214

13-
/// The stack of nested nodes.
15+
/// The stack of nested statements.
1416
final List<Set<Element>> _stack = [];
1517

1618
AssignedVariables();
@@ -21,12 +23,12 @@ class AssignedVariables<Statement, Element> {
2123
return _map[statement] ?? emptySet;
2224
}
2325

24-
void beginLoop() {
26+
void beginStatement() {
2527
var set = Set<Element>.identity();
2628
_stack.add(set);
2729
}
2830

29-
void endLoop(Statement node) {
31+
void endStatement(Statement node) {
3032
_map[node] = _stack.removeLast();
3133
}
3234

@@ -126,6 +128,17 @@ class FlowAnalysis<Statement, Expression, Element, Type> {
126128
_current = _current.add(variable, assigned: assigned);
127129
}
128130

131+
void booleanLiteral(Expression expression, bool value) {
132+
_condition = expression;
133+
if (value) {
134+
_conditionTrue = _current;
135+
_conditionFalse = _identity;
136+
} else {
137+
_conditionTrue = _identity;
138+
_conditionFalse = _current;
139+
}
140+
}
141+
129142
void conditional_elseBegin(Expression conditionalExpression,
130143
Expression thenExpression, bool isBool) {
131144
var afterThen = _current;
@@ -223,12 +236,6 @@ class FlowAnalysis<Statement, Expression, Element, Type> {
223236
_current = _join(falseCondition, breakState);
224237
}
225238

226-
void falseLiteral(Expression expression) {
227-
_condition = expression;
228-
_conditionTrue = _identity;
229-
_conditionFalse = _current;
230-
}
231-
232239
void forEachStatement_bodyBegin(Set<Element> loopAssigned) {
233240
_stack.add(_current);
234241
_current = _current.removePromotedAll(loopAssigned);
@@ -494,12 +501,6 @@ class FlowAnalysis<Statement, Expression, Element, Type> {
494501
_stack.add(_current); // afterExpression
495502
}
496503

497-
void trueLiteral(Expression expression) {
498-
_condition = expression;
499-
_conditionTrue = _current;
500-
_conditionFalse = _identity;
501-
}
502-
503504
void tryCatchStatement_bodyBegin() {
504505
_stack.add(_current);
505506
// Tail of the stack: beforeBody

0 commit comments

Comments
 (0)