Issue 48502. Report RETHROW_OUTSIDE_CATCH when new executable inside catch.
Bug: https://github.com/dart-lang/sdk/issues/48502
Change-Id: Iddab4ff30eca7da4891916ac051ad9a827a252e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235170
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c923c69..01ff198 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -74,6 +74,9 @@
/// for the kind of the function body, e.g. not `Future` for `async`.
bool hasLegalReturnType = true;
+ /// The number of enclosing [CatchClause] in this executable.
+ int catchClauseLevel = 0;
+
EnclosingExecutableContext(this.element,
{bool? isAsynchronous, this.catchErrorOnErrorReturnType})
: isAsynchronous =
@@ -164,11 +167,6 @@
/// The manager for the inheritance mappings.
final InheritanceManager3 _inheritanceManager;
- /// A flag indicating whether the visitor is currently within a catch clause.
- ///
- /// See [visitCatchClause].
- bool _isInCatchClause = false;
-
/// A flag indicating whether the visitor is currently within a comment.
bool _isInComment = false;
@@ -250,7 +248,6 @@
_duplicateDefinitionVerifier = DuplicateDefinitionVerifier(
_inheritanceManager, _currentLibrary, errorReporter) {
_isInSystemLibrary = _currentLibrary.source.uri.isScheme('dart');
- _isInCatchClause = false;
_isInStaticVariableDeclaration = false;
_isInConstructorInitializer = false;
_intType = _typeProvider.intType;
@@ -409,13 +406,12 @@
@override
void visitCatchClause(CatchClause node) {
_duplicateDefinitionVerifier.checkCatchClause(node);
- bool previousIsInCatchClause = _isInCatchClause;
try {
- _isInCatchClause = true;
+ _enclosingExecutable.catchClauseLevel++;
_checkForTypeAnnotationDeferredClass(node.exceptionType);
super.visitCatchClause(node);
} finally {
- _isInCatchClause = previousIsInCatchClause;
+ _enclosingExecutable.catchClauseLevel--;
}
}
@@ -4112,7 +4108,7 @@
///
/// See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH].
void _checkForRethrowOutsideCatch(RethrowExpression expression) {
- if (!_isInCatchClause) {
+ if (_enclosingExecutable.catchClauseLevel == 0) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression);
}
diff --git a/pkg/analyzer/test/src/diagnostics/rethrow_outside_catch_test.dart b/pkg/analyzer/test/src/diagnostics/rethrow_outside_catch_test.dart
index ee8c262..717c3a4 100644
--- a/pkg/analyzer/test/src/diagnostics/rethrow_outside_catch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/rethrow_outside_catch_test.dart
@@ -17,9 +17,37 @@
class RethrowOutsideCatchTest extends PubPackageResolutionTest {
test_insideCatch() async {
await assertNoErrorsInCode(r'''
-class A {
- void m() {
- try {} catch (e) {rethrow;}
+void f() {
+ try {} catch (e) {
+ rethrow;
+ }
+}
+''');
+ }
+
+ test_insideCatch_insideClosure() async {
+ await assertErrorsInCode(r'''
+void f() {
+ try {} catch (e) {
+ () {
+ rethrow;
+ };
+ }
+}
+''', [
+ error(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, 47, 7),
+ ]);
+ }
+
+ test_insideCatch_insideClosure_insideCatch() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ try {} catch (e1) {
+ () {
+ try {} catch (e2) {
+ rethrow;
+ }
+ };
}
}
''');
@@ -27,11 +55,11 @@
test_withoutCatch() async {
await assertErrorsInCode(r'''
-f() {
+void f() {
rethrow;
}
''', [
- error(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, 8, 7),
+ error(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, 13, 7),
]);
}
}