Skip to content

Commit bff5732

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Flow analysis: unify API for handling == null and != null.
This reduces code duplication in the client. Change-Id: I278fb4d3c7fc7b913498d4a69f4f361f6227da32 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112146 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
1 parent a7af48f commit bff5732

File tree

4 files changed

+24
-57
lines changed

4 files changed

+24
-57
lines changed

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

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:analyzer/dart/element/type_system.dart';
1111
import 'package:analyzer/src/dart/element/type.dart';
1212
import 'package:analyzer/src/generated/variable_type_provider.dart';
1313
import 'package:front_end/src/fasta/flow_analysis/flow_analysis.dart';
14+
import 'package:meta/meta.dart';
1415

1516
class AnalyzerFunctionBodyAccess
1617
implements FunctionBodyAccess<VariableElement> {
@@ -104,49 +105,23 @@ class FlowAnalysisHelper {
104105
flow.write(localElement);
105106
}
106107

107-
void binaryExpression_bangEq(
108-
BinaryExpression node,
109-
Expression left,
110-
Expression right,
111-
) {
108+
void binaryExpression_equal(
109+
BinaryExpression node, Expression left, Expression right,
110+
{@required bool notEqual}) {
112111
if (flow == null) return;
113112

114113
if (right is NullLiteral) {
115114
if (left is SimpleIdentifier) {
116115
var element = left.staticElement;
117116
if (element is VariableElement) {
118-
flow.conditionNotEqNull(node, element);
117+
flow.conditionEqNull(node, element, notEqual: notEqual);
119118
}
120119
}
121120
} else if (left is NullLiteral) {
122121
if (right is SimpleIdentifier) {
123122
var element = right.staticElement;
124123
if (element is VariableElement) {
125-
flow.conditionNotEqNull(node, element);
126-
}
127-
}
128-
}
129-
}
130-
131-
void binaryExpression_eqEq(
132-
BinaryExpression node,
133-
Expression left,
134-
Expression right,
135-
) {
136-
if (flow == null) return;
137-
138-
if (right is NullLiteral) {
139-
if (left is SimpleIdentifier) {
140-
var element = left.staticElement;
141-
if (element is VariableElement) {
142-
flow.conditionEqNull(node, element);
143-
}
144-
}
145-
} else if (left is NullLiteral) {
146-
if (right is SimpleIdentifier) {
147-
var element = right.staticElement;
148-
if (element is VariableElement) {
149-
flow.conditionEqNull(node, element);
124+
flow.conditionEqNull(node, element, notEqual: notEqual);
150125
}
151126
}
152127
}

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,16 +3449,12 @@ class ResolverVisitor extends ScopedVisitor {
34493449
flow?.logicalOr_end(node, right);
34503450

34513451
node.accept(elementResolver);
3452-
} else if (operator == TokenType.BANG_EQ) {
3452+
} else if (operator == TokenType.BANG_EQ || operator == TokenType.EQ_EQ) {
34533453
left.accept(this);
34543454
right.accept(this);
34553455
node.accept(elementResolver);
3456-
_flowAnalysis?.binaryExpression_bangEq(node, left, right);
3457-
} else if (operator == TokenType.EQ_EQ) {
3458-
left.accept(this);
3459-
right.accept(this);
3460-
node.accept(elementResolver);
3461-
_flowAnalysis?.binaryExpression_eqEq(node, left, right);
3456+
_flowAnalysis?.binaryExpression_equal(node, left, right,
3457+
notEqual: operator == TokenType.BANG_EQ);
34623458
} else {
34633459
if (operator == TokenType.QUESTION_QUESTION) {
34643460
InferenceContext.setTypeFromNode(left, node);

pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,28 +187,24 @@ class FlowAnalysis<Statement, Expression, Variable, Type> {
187187
_current = trueCondition;
188188
}
189189

190-
/// The [binaryExpression] checks that the [variable] is equal to `null`.
191-
void conditionEqNull(Expression binaryExpression, Variable variable) {
190+
/// The [binaryExpression] checks that the [variable] is, or is not, equal to
191+
/// `null`.
192+
void conditionEqNull(Expression binaryExpression, Variable variable,
193+
{bool notEqual: false}) {
192194
_variableReferenced(variable);
193195
if (functionBody.isPotentiallyMutatedInClosure(variable)) {
194196
return;
195197
}
196198

197199
_condition = binaryExpression;
198-
_conditionTrue = _current;
199-
_conditionFalse = _current.markNonNullable(typeOperations, variable);
200-
}
201-
202-
/// The [binaryExpression] checks that the [variable] is not equal to `null`.
203-
void conditionNotEqNull(Expression binaryExpression, Variable variable) {
204-
_variableReferenced(variable);
205-
if (functionBody.isPotentiallyMutatedInClosure(variable)) {
206-
return;
200+
var currentPromoted = _current.markNonNullable(typeOperations, variable);
201+
if (notEqual) {
202+
_conditionTrue = currentPromoted;
203+
_conditionFalse = _current;
204+
} else {
205+
_conditionTrue = _current;
206+
_conditionFalse = currentPromoted;
207207
}
208-
209-
_condition = binaryExpression;
210-
_conditionTrue = _current.markNonNullable(typeOperations, variable);
211-
_conditionFalse = _current;
212208
}
213209

214210
void doStatement_bodyBegin(

pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import 'package:test/test.dart';
77

88
main() {
99
group('API', () {
10-
test('conditionNotEqNull promotes true branch', () {
10+
test('conditionEqNull(notEqual: true) promotes true branch', () {
1111
var h = _Harness();
1212
var x = h.addAssignedVar('x', 'int?');
1313
var expr = _Expression();
14-
h.flow.conditionNotEqNull(expr, x);
14+
h.flow.conditionEqNull(expr, x, notEqual: true);
1515
h.flow.ifStatement_thenBegin(expr);
1616
expect(h.flow.promotedType(x).type, 'int');
1717
h.flow.ifStatement_elseBegin();
@@ -20,11 +20,11 @@ main() {
2020
h.flow.finish();
2121
});
2222

23-
test('conditionEqNull promotes false branch', () {
23+
test('conditionEqNull(notEqual: false) promotes false branch', () {
2424
var h = _Harness();
2525
var x = h.addAssignedVar('x', 'int?');
2626
var expr = _Expression();
27-
h.flow.conditionEqNull(expr, x);
27+
h.flow.conditionEqNull(expr, x, notEqual: false);
2828
h.flow.ifStatement_thenBegin(expr);
2929
expect(h.flow.promotedType(x), isNull);
3030
h.flow.ifStatement_elseBegin();

0 commit comments

Comments
 (0)