Skip to content

Commit 0549def

Browse files
author
John Messerly
committed
checking and inference of null coalescing operator, fixes #24564 and fixes #25387
[email protected] Review URL: https://codereview.chromium.org/1575173005 .
1 parent c85916d commit 0549def

File tree

4 files changed

+27
-5
lines changed

4 files changed

+27
-5
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8435,7 +8435,11 @@ class ResolverVisitor extends ScopedVisitor {
84358435
}
84368436
} else {
84378437
// TODO(leafp): Do downwards inference using the declared type
8438-
// of the binary operator.
8438+
// of the binary operator for other cases.
8439+
if (operatorType == TokenType.QUESTION_QUESTION) {
8440+
InferenceContext.setTypeFromNode(leftOperand, node);
8441+
InferenceContext.setTypeFromNode(rightOperand, node);
8442+
}
84398443
safelyVisit(leftOperand);
84408444
safelyVisit(rightOperand);
84418445
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
330330
@override
331331
Object visitBinaryExpression(BinaryExpression node) {
332332
if (node.operator.type == TokenType.QUESTION_QUESTION) {
333-
// Evaluation of an if-null expresion e of the form e1 ?? e2 is
333+
// Evaluation of an if-null expression e of the form e1 ?? e2 is
334334
// equivalent to the evaluation of the expression
335335
// ((x) => x == null ? e2 : x)(e1). The static type of e is the least
336336
// upper bound of the static type of e1 and the static type of e2.

pkg/analyzer/lib/src/task/strong/checker.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,12 @@ class CodeChecker extends RecursiveAstVisitor {
189189
@override
190190
void visitAssignmentExpression(AssignmentExpression node) {
191191
var token = node.operator;
192-
if (token.type != TokenType.EQ) {
193-
_checkCompoundAssignment(node);
194-
} else {
192+
if (token.type == TokenType.EQ ||
193+
token.type == TokenType.QUESTION_QUESTION_EQ) {
195194
DartType staticType = _getStaticType(node.leftHandSide);
196195
checkAssignment(node.rightHandSide, staticType);
196+
} else {
197+
_checkCompoundAssignment(node);
197198
}
198199
node.visitChildren(this);
199200
}

pkg/analyzer/test/src/task/strong/checker_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,23 @@ void main() {
14931493
'''
14941494
});
14951495

1496+
testChecker('null coalescing operator', {
1497+
'/main.dart': '''
1498+
class A {}
1499+
class C<T> {}
1500+
main() {
1501+
A a, b;
1502+
a ??= new A();
1503+
b = b ?? new A();
1504+
1505+
// downwards inference
1506+
C<int> c, d;
1507+
c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
1508+
d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
1509+
}
1510+
'''
1511+
});
1512+
14961513
testChecker('compound assignments', {
14971514
'/main.dart': '''
14981515
class A {

0 commit comments

Comments
 (0)