From 60678333286c157837cc9bda96dee07212a29c06 Mon Sep 17 00:00:00 2001 From: pq Date: Fri, 12 Jul 2024 21:57:40 +0000 Subject: [PATCH] [wildcards] report dead late wildcard variable initializers Fixes: https://github.com/dart-lang/sdk/issues/55905 Change-Id: I78f40c754ae2daf0894b7a2b114a739c60214f72 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/375200 Reviewed-by: Brian Wilkerson Commit-Queue: Phil Quitslund --- .../services/correction/error_fix_status.yaml | 6 +++- pkg/analyzer/lib/src/error/codes.g.dart | 13 ++++++++ .../lib/src/error/dead_code_verifier.dart | 17 +++++++++++ .../lib/src/error/error_code_values.g.dart | 1 + pkg/analyzer/messages.yaml | 6 ++++ .../test/src/diagnostics/dead_code_test.dart | 30 ++++++++++++++++++- pkg/analyzer/tool/diagnostics/diagnostics.md | 3 ++ 7 files changed, 74 insertions(+), 2 deletions(-) diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml index 091e8ae34e58..da263a5976e9 100644 --- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml +++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml @@ -45,7 +45,7 @@ # # Stats: # - 42 "needsEvaluation" -# - 306 "needsFix" +# - 307 "needsFix" # - 441 "hasFix" # - 517 "noFix" @@ -3389,6 +3389,10 @@ WarningCode.DEAD_CODE: status: hasFix WarningCode.DEAD_CODE_CATCH_FOLLOWING_CATCH: status: hasFix +WarningCode.DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER: + status: needsFix + notes: |- + Remove the initializer or remove the late keyword. WarningCode.DEAD_CODE_ON_CATCH_SUBTYPE: status: hasFix WarningCode.DEPRECATED_EXPORT_USE: diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart index 5a281b5b7128..eba710cde2c7 100644 --- a/pkg/analyzer/lib/src/error/codes.g.dart +++ b/pkg/analyzer/lib/src/error/codes.g.dart @@ -6288,6 +6288,19 @@ class WarningCode extends AnalyzerErrorCode { hasPublishedDocs: true, ); + /// No parameters. + static const WarningCode DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER = + WarningCode( + 'DEAD_CODE', + "Dead code: The assigned-to wildcard variable is marked late and can never " + "be referenced so this initializer will never be evaluated.", + correctionMessage: + "Try removing the code, removing the late modifier or changing the " + "variable to a non-wildcard.", + hasPublishedDocs: true, + uniqueName: 'DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER', + ); + /// Dead code is code that is never reached. This case covers cases where the /// user has an on-catch clause such as `on A catch (e)`, where a supertype of /// `A` was already caught. diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart index 4f42fa8daedc..5aa44167e7af 100644 --- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart +++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart @@ -111,6 +111,23 @@ class DeadCodeVerifier extends RecursiveAstVisitor { }); } + @override + void visitVariableDeclaration(VariableDeclaration node) { + var initializer = node.initializer; + if (initializer != null && node.isLate) { + var element = node.declaredElement; + // TODO(pq): ask the LocalVariableElement once implemented + if (_wildCardVariablesEnabled && + element is LocalVariableElement && + element.name == '_') { + _errorReporter.atNode(initializer, + WarningCode.DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER); + } + } + + super.visitVariableDeclaration(node); + } + /// Resolve the names in the given [combinator] in the scope of the given /// [library]. void _checkCombinator(LibraryElement library, Combinator combinator) { diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart index 6f78feca7706..4f0d692d0fae 100644 --- a/pkg/analyzer/lib/src/error/error_code_values.g.dart +++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart @@ -983,6 +983,7 @@ const List errorCodeValues = [ WarningCode.CONSTANT_PATTERN_NEVER_MATCHES_VALUE_TYPE, WarningCode.DEAD_CODE, WarningCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, + WarningCode.DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER, WarningCode.DEAD_CODE_ON_CATCH_SUBTYPE, WarningCode.DEPRECATED_EXPORT_USE, WarningCode.DEPRECATED_EXTENDS_FUNCTION, diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index bd496d9eb677..66d79e95540e 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -23360,6 +23360,12 @@ WarningCode: } } ``` + DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER: + problemMessage: "Dead code: The assigned-to wildcard variable is marked late and can never be referenced so this initializer will never be evaluated." + correctionMessage: Try removing the code, removing the late modifier or changing the variable to a non-wildcard. + sharedName: DEAD_CODE + hasPublishedDocs: true + comment: No parameters. DEAD_CODE_ON_CATCH_SUBTYPE: problemMessage: "Dead code: This on-catch block won't be executed because '{0}' is a subtype of '{1}' and hence will have been caught already." correctionMessage: Try reordering the catch clauses so that this block can be reached, or removing the unreachable catch clause. diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart index b02ba73bc97a..4e8665eaebd6 100644 --- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart +++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart @@ -178,7 +178,17 @@ void f(Object x) { @reflectiveTest class DeadCodeTest_Language219 extends PubPackageResolutionTest - with WithLanguage219Mixin, DeadCodeTestCases_Language212 {} + with WithLanguage219Mixin, DeadCodeTestCases_Language212 { + @override + test_lateWildCardVariable_initializer() async { + await assertNoErrorsInCode(r''' +f() { + // Not a wildcard variable. + late var _ = 0; +} +'''); + } +} mixin DeadCodeTestCases_Language212 on PubPackageResolutionTest { @override @@ -1192,6 +1202,24 @@ void g(Never f) { ]); } + test_lateWildCardVariable_initializer() async { + await assertErrorsInCode(r''' +f() { + late var _ = 0; +} +''', [ + error(WarningCode.DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER, 21, 1), + ]); + } + + test_lateWildCardVariable_noInitializer() async { + await assertNoErrorsInCode(r''' +f() { + late var _; +} +'''); + } + test_notUnassigned_propertyAccess() async { await assertNoErrorsInCode(r''' void f(int? i) { diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md index 7b46a19ab879..276f604c1476 100644 --- a/pkg/analyzer/tool/diagnostics/diagnostics.md +++ b/pkg/analyzer/tool/diagnostics/diagnostics.md @@ -3651,6 +3651,9 @@ void g() { _Dead code._ +_Dead code: The assigned-to wildcard variable is marked late and can never be +referenced so this initializer will never be evaluated._ + #### Description The analyzer produces this diagnostic when code is found that won't be