From 592914fb8bb66efe040781e462f67957669ba768 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 5 Sep 2019 20:26:12 +0000 Subject: [PATCH] Don't report HintCode.CAN_BE_NULL_AFTER_NULL_AWARE when NNBD. With NNBD we do shorting, so `foo?.bar.baz` is OK, `baz` will never be requested from `null`, unless `foo.bar` is nullable, in which case it is UNCHECKED_USE_OF_NULLABLE_VALUE. R=brianwilkerson@google.com Change-Id: Ic9bbd0f6116dfca53b8dd9cf05b557919c025d2d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115762 Reviewed-by: Brian Wilkerson Commit-Queue: Konstantin Shcheglov --- pkg/analyzer/lib/src/generated/resolver.dart | 8 ++++++++ .../diagnostics/unchecked_use_of_nullable_value_test.dart | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index ae030779292f7..bfb3f3e2398dd 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -93,6 +93,9 @@ class BestPracticesVerifier extends RecursiveAstVisitor { /// The [LinterContext] used for possible const calculations. LinterContext _linterContext; + /// Is `true` if NNBD is enabled for the library being analyzed. + final bool _isNonNullable; + /// Create a new instance of the [BestPracticesVerifier]. /// /// @param errorReporter the error reporter @@ -110,6 +113,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor { }) : _nullType = typeProvider.nullType, _futureNullType = typeProvider.futureNullType, _typeSystem = typeSystem ?? new Dart2TypeSystem(typeProvider), + _isNonNullable = unit.featureSet.isEnabled(Feature.non_nullable), _inheritanceManager = inheritanceManager, _invalidAccessVerifier = new _InvalidAccessVerifier(_errorReporter, _currentLibrary) { @@ -918,6 +922,10 @@ class BestPracticesVerifier extends RecursiveAstVisitor { /// Produce several null-aware related hints. void _checkForNullAwareHints(Expression node, Token operator) { + if (_isNonNullable) { + return; + } + if (operator == null || operator.type != TokenType.QUESTION_PERIOD) { return; } diff --git a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart index cf21331e46896..a5176b96cf921 100644 --- a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart +++ b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart @@ -805,8 +805,6 @@ m(B? b) { b.a.x; // 2 } ''', [ - // TODO(scheglov) Remove HintCode.CAN_BE_NULL_AFTER_NULL_AWARE - error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 86, 4), error(StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 101, 1), ]); var propertyAccess1 = findNode.propertyAccess('x; // 1'); @@ -879,8 +877,6 @@ m(C c) { c.b.a.x; // 2 } ''', [ - // TODO(scheglov) Remove HintCode.CAN_BE_NULL_AFTER_NULL_AWARE - error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 131, 6), error(StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 148, 3), ]); var propertyAccess1 = findNode.propertyAccess('x; // 1');