Skip to content

Commit 421a968

Browse files
FMorschelCommit Queue
authored andcommitted
[DAS] Fixes Add missing Switch cases not importing src libraries
Fixes: #60531 Change-Id: I6ca063aeaad2b6ce994c8637da653561231b1fdf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/451340 Auto-Submit: Felipe Morschel <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 9052ec7 commit 421a968

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

pkg/analysis_server/lib/src/services/correction/dart/add_missing_switch_cases.dart

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:analysis_server/src/services/correction/fix.dart';
66
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
77
import 'package:analyzer/dart/ast/ast.dart';
8+
import 'package:analyzer/dart/element/element.dart';
89
import 'package:analyzer/diagnostic/diagnostic.dart';
910
import 'package:analyzer/src/generated/exhaustiveness.dart';
1011
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -57,9 +58,8 @@ class AddMissingSwitchCases extends ResolvedCorrectionProducer {
5758
/// Returns whether [parts] references an enum field where either the enum
5859
/// class itself or the missing field is not reachable because it's private.
5960
bool _hasInaccessibleEnumMemberPart(List<MissingPatternPart> parts) {
60-
for (var part in parts) {
61-
if (part is MissingPatternEnumValuePart &&
62-
(part.enumElement2.isPrivate || part.value2.isPrivate) &&
61+
for (var part in parts.whereType<MissingPatternEnumValuePart>()) {
62+
if ((part.enumElement2.isPrivate || part.value2.isPrivate) &&
6363
libraryElement2 != part.enumElement2.library) {
6464
return true;
6565
}
@@ -68,6 +68,21 @@ class AddMissingSwitchCases extends ResolvedCorrectionProducer {
6868
return false;
6969
}
7070

71+
/// Returns whether [parts] references a type from within a `src/` library
72+
/// that is not from the current project.
73+
Future<bool> _hasInaccessibleTypePart(List<MissingPatternPart> parts) async {
74+
for (var part in parts.whereType<MissingPatternTypePart>()) {
75+
if (part.type.element case Element(:var name?) && var element) {
76+
var declarations = await getTopLevelDeclarations(name);
77+
if (!declarations.containsValue(element)) {
78+
return true;
79+
}
80+
}
81+
}
82+
83+
return false;
84+
}
85+
7186
Future<void> _switchExpression({
7287
required ChangeBuilder builder,
7388
required SwitchExpression node,
@@ -80,6 +95,16 @@ class AddMissingSwitchCases extends ResolvedCorrectionProducer {
8095
// of the switch. For instance, an enum with a private member can't be
8196
// matched outside of its library.
8297
var needsDefault = false;
98+
for (var patternParts in patternPartsList.toList()) {
99+
if (_hasInaccessibleEnumMemberPart(patternParts)) {
100+
needsDefault = true;
101+
patternPartsList.remove(patternParts);
102+
}
103+
if (await _hasInaccessibleTypePart(patternParts)) {
104+
patternPartsList.remove(patternParts);
105+
needsDefault = true;
106+
}
107+
}
83108

84109
await builder.addDartFileEdit(file, (builder) {
85110
builder.insertCaseClauseAtEnd(
@@ -89,11 +114,6 @@ class AddMissingSwitchCases extends ResolvedCorrectionProducer {
89114
rightBracket: node.rightBracket,
90115
(builder) {
91116
for (var patternParts in patternPartsList) {
92-
if (_hasInaccessibleEnumMemberPart(patternParts)) {
93-
needsDefault = true;
94-
continue;
95-
}
96-
97117
builder.write(lineIndent);
98118
builder.write(singleIndent);
99119
builder.writeln('// TODO: Handle this case.');

pkg/analysis_server/test/src/services/correction/fix/add_missing_switch_cases_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:analysis_server/src/services/correction/fix.dart';
66
import 'package:analyzer/diagnostic/diagnostic.dart';
77
import 'package:analyzer/src/error/codes.dart';
8+
import 'package:analyzer/utilities/package_config_file_builder.dart';
89
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
910
import 'package:linter/src/lint_names.dart';
1011
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -354,6 +355,44 @@ int f(num x) {
354355
int() => throw UnimplementedError(),
355356
};
356357
}
358+
''');
359+
}
360+
361+
Future<void> test_sealed_impl() async {
362+
var otherRoot = getFolder('$packagesRootPath/other');
363+
newFile('$otherRoot/lib/src/private.dart', '''
364+
sealed class A {}
365+
sealed class B implements A {}
366+
abstract final class C implements B {}
367+
final class CImpl extends B implements C {}
368+
''');
369+
newFile('$otherRoot/lib/exposed.dart', '''
370+
export 'src/private.dart' show A, B, C;
371+
''');
372+
updateTestPubspecFile('''
373+
name: test
374+
dependencies:
375+
other: any
376+
''');
377+
writeTestPackageConfig(
378+
config: PackageConfigFileBuilder()
379+
..add(name: 'other', rootPath: otherRoot.path),
380+
);
381+
await resolveTestCode('''
382+
import 'package:other/exposed.dart';
383+
384+
int f(A a) => switch (a) {
385+
};
386+
''');
387+
await assertHasFix('''
388+
import 'package:other/exposed.dart';
389+
390+
int f(A a) => switch (a) {
391+
// TODO: Handle this case.
392+
C() => throw UnimplementedError(),
393+
// TODO: Handle this case.
394+
_ => throw UnimplementedError(),
395+
};
357396
''');
358397
}
359398
}

0 commit comments

Comments
 (0)