diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart index 3318bc350b7..4adfcc2e492 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart @@ -42,6 +42,12 @@ class JoinIfWithInner extends ResolvedCorrectionProducer { if (innerIfStatement.elseStatement != null) { return; } + + // If inner is if-case, we cannot join them. + if (innerIfStatement.caseClause != null) { + return; + } + // prepare environment var prefix = utils.getNodePrefix(targetIfStatement); // merge conditions @@ -55,7 +61,30 @@ class JoinIfWithInner extends ResolvedCorrectionProducer { if (innerCondition.shouldWrapParenthesisBeforeAnd) { innerConditionSource = '($innerConditionSource)'; } + var condition = '$targetConditionSource && $innerConditionSource'; + + // If outer is if-case. + var outerCaseClause = targetIfStatement.caseClause; + if (outerCaseClause != null) { + var casePattern = outerCaseClause.guardedPattern.pattern; + var caseWhenExpression = + outerCaseClause.guardedPattern.whenClause?.expression; + + if (caseWhenExpression != null) { + var caseWhenSource = '$caseWhenExpression'; + if (caseWhenExpression.shouldWrapParenthesisBeforeAnd) { + caseWhenSource = '($caseWhenSource)'; + } + + condition = + '$targetConditionSource case $casePattern when $caseWhenSource && $innerConditionSource'; + } else { + condition = + '$targetConditionSource case $casePattern when $innerConditionSource'; + } + } + // replace target "if" statement var innerThenStatement = innerIfStatement.thenStatement; var innerThenStatements = getStatements(innerThenStatement); diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart index c863811f6c6..59acee8ca9c 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart @@ -48,6 +48,12 @@ class JoinIfWithOuter extends ResolvedCorrectionProducer { if (outerIfStatement.elseStatement != null) { return; } + + // If target (inner) is if-case, we cannot join them. + if (targetIfStatement.caseClause != null) { + return; + } + // prepare environment var prefix = utils.getNodePrefix(outerIfStatement); // merge conditions @@ -61,7 +67,30 @@ class JoinIfWithOuter extends ResolvedCorrectionProducer { if (outerCondition.shouldWrapParenthesisBeforeAnd) { outerConditionSource = '($outerConditionSource)'; } + var condition = '$outerConditionSource && $targetConditionSource'; + + // If outer is if-case. + var outerCaseClause = outerIfStatement.caseClause; + if (outerCaseClause != null) { + var casePattern = outerCaseClause.guardedPattern.pattern; + var caseWhenExpression = + outerCaseClause.guardedPattern.whenClause?.expression; + + if (caseWhenExpression != null) { + var caseWhenSource = '$caseWhenExpression'; + if (caseWhenExpression.shouldWrapParenthesisBeforeAnd) { + caseWhenSource = '($caseWhenSource)'; + } + + condition = + '$outerConditionSource case $casePattern when $caseWhenSource && $targetConditionSource'; + } else { + condition = + '$outerConditionSource case $casePattern when $targetConditionSource'; + } + } + // replace outer "if" statement var targetThenStatement = targetIfStatement.thenStatement; var targetThenStatements = getStatements(targetThenStatement); diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart index c24a5983081..60819034312 100644 --- a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart +++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart @@ -19,6 +19,19 @@ class JoinIfWithInnerTest extends AssistProcessorTest { @override AssistKind get kind => DartAssistKind.JOIN_IF_WITH_INNER; + Future test_bothOuterAndInnerAreIfCase() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final v?) { + if (v case final int x) { + print(0); + } + } +} +'''); + await assertNoAssistAt('if (p'); + } + Future test_conditionAndOr() async { await resolveTestCode(''' void f() { @@ -78,6 +91,120 @@ void f() { '''); } + Future test_ifCaseAddWhen() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p) { + if (p case final int v when v == 5) { + print(0); + } +} +'''); + } + + Future test_ifCaseAddWhenUnrelated() async { + await resolveTestCode(''' +void f(Object? p, Object? q) { + if (p case final int v) { + if (q != null) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p, Object? q) { + if (p case final int v when q != null) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhen() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p) { + if (p case final int v when v.isOdd && v == 5) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisBoth() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd || v > 3) { + if (v == 5 || v != 6) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p) { + if (p case final int v when (v.isOdd || v > 3) && (v == 5 || v != 6)) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisInner() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd) { + if (v == 5 || v != 3) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p) { + if (p case final int v when v.isOdd && (v == 5 || v != 3)) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisOuter() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd || v != 3) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (p', ''' +void f(Object? p) { + if (p case final int v when (v.isOdd || v != 3) && v == 5) { + print(0); + } +} +'''); + } + Future test_innerNotIf() async { await resolveTestCode(''' void f() { diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart index 54860825957..824df47e83f 100644 --- a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart +++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart @@ -19,6 +19,19 @@ class JoinIfWithOuterTest extends AssistProcessorTest { @override AssistKind get kind => DartAssistKind.JOIN_IF_WITH_OUTER; + Future test_bothOuterAndInnerAreIfCase() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final v?) { + if (v case final int x) { + print(x); + } + } +} +'''); + await assertNoAssistAt('if (v'); + } + Future test_conditionAndOr() async { await resolveTestCode(''' void f() { @@ -78,6 +91,120 @@ void f() { '''); } + Future test_ifCaseAddWhen() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (v == 5', ''' +void f(Object? p) { + if (p case final int v when v == 5) { + print(0); + } +} +'''); + } + + Future test_ifCaseAddWhenUnrelated() async { + await resolveTestCode(''' +void f(Object? p, Object? q) { + if (p case final int v) { + if (q != null) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (q != null', ''' +void f(Object? p, Object? q) { + if (p case final int v when q != null) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhen() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (v == 5', ''' +void f(Object? p) { + if (p case final int v when v.isOdd && v == 5) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisBoth() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd || v > 3) { + if (v == 5 || v != 6) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (v', ''' +void f(Object? p) { + if (p case final int v when (v.isOdd || v > 3) && (v == 5 || v != 6)) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisInner() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd) { + if (v == 5 || v != 3) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (v', ''' +void f(Object? p) { + if (p case final int v when v.isOdd && (v == 5 || v != 3)) { + print(0); + } +} +'''); + } + + Future test_ifCaseAppendWhenWithParenthesisOuter() async { + await resolveTestCode(''' +void f(Object? p) { + if (p case final int v when v.isOdd || v != 3) { + if (v == 5) { + print(0); + } + } +} +'''); + await assertHasAssistAt('if (v', ''' +void f(Object? p) { + if (p case final int v when (v.isOdd || v != 3) && v == 5) { + print(0); + } +} +'''); + } + Future test_onCondition() async { await resolveTestCode(''' void f() {