Skip to content

Commit 68ba13e

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
With NNBD null-shorting is performed.
So, the type of `a?.b.c` is nullable, but the type of `c` is not. Everything after `a?` is just not executed if `a` is null. [email protected] Change-Id: I705051080b8cc2bb5014355688561b0f3dccc0d8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115660 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent a7723d5 commit 68ba13e

File tree

3 files changed

+328
-12
lines changed

3 files changed

+328
-12
lines changed

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4364,13 +4364,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
43644364
StaticWarningCode code = expression.staticType == _typeProvider.nullType
43654365
? StaticWarningCode.INVALID_USE_OF_NULL_VALUE
43664366
: StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE;
4367-
4368-
if (expression is MethodInvocation) {
4369-
SimpleIdentifier methodName = expression.methodName;
4370-
_errorReporter.reportErrorForNode(code, methodName, []);
4371-
} else {
4372-
_errorReporter.reportErrorForNode(code, expression, []);
4373-
}
4367+
_errorReporter.reportErrorForNode(code, expression, []);
43744368

43754369
return true;
43764370
}

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

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
332332
_featureSet);
333333
_recordStaticType(node, staticType);
334334
}
335+
_nullShortingTermination(node);
335336
}
336337

337338
/**
@@ -967,15 +968,12 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
967968
// TODO(brianwilkerson) Report this internal error.
968969
}
969970

970-
if (node.operator.type == TokenType.QUESTION_PERIOD &&
971-
_nonNullableEnabled) {
972-
staticType = _typeSystem.makeNullable(staticType);
973-
}
974971
staticType = _inferTearOff(node, node.propertyName, staticType);
975972

976973
if (!_inferObjectAccess(node, staticType, propertyName)) {
977974
_recordStaticType(propertyName, staticType);
978975
_recordStaticType(node, staticType);
976+
_nullShortingTermination(node);
979977
}
980978
}
981979

@@ -2006,6 +2004,25 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
20062004
return type;
20072005
}
20082006

2007+
/// If we reached a null-shorting termination, and the [node] has null
2008+
/// shorting, make the type of the [node] nullable.
2009+
void _nullShortingTermination(Expression node) {
2010+
if (!_nonNullableEnabled) return;
2011+
2012+
var parent = node.parent;
2013+
if (parent is AssignmentExpression && parent.leftHandSide == node) {
2014+
return;
2015+
}
2016+
if (parent is PropertyAccess) {
2017+
return;
2018+
}
2019+
2020+
if (_hasNullShorting(node)) {
2021+
var type = node.staticType;
2022+
node.staticType = _typeSystem.makeNullable(type);
2023+
}
2024+
}
2025+
20092026
/**
20102027
* Record that the static type of the given node is the given type.
20112028
*
@@ -2120,6 +2137,18 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
21202137
return type;
21212138
}
21222139
}
2140+
2141+
/// Return `true` if the [node] has null-aware shorting, e.g. `foo?.bar`.
2142+
static bool _hasNullShorting(Expression node) {
2143+
if (node is AssignmentExpression) {
2144+
return _hasNullShorting(node.leftHandSide);
2145+
}
2146+
if (node is PropertyAccess) {
2147+
return node.operator.type == TokenType.QUESTION_PERIOD ||
2148+
_hasNullShorting(node.target);
2149+
}
2150+
return false;
2151+
}
21232152
}
21242153

21252154
class _InferredCollectionElementTypeInformation {

0 commit comments

Comments
 (0)