Skip to content

Commit dd99416

Browse files
authored
[CQ] fix nullability problems for flutter/actions (#8293)
Fix nullability problems for all the actions in `src/io/flutter/actions/`. See #8291. If we pursue #8292, we could mark `src/io/flutter/actions/` as null-"clean". --- - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. <details> <summary>Contribution guidelines:</summary><br> - See our [contributor guide]([https://github.com/dart-lang/sdk/blob/main/CONTRIBUTING.md](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](#8098)). </details>
1 parent 7036e1c commit dd99416

20 files changed

+169
-87
lines changed

flutter-idea/src/io/flutter/actions/AttachDebuggerAction.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public boolean enableActionInBazelContext() {
125125
}
126126

127127
@Override
128-
public void update(AnActionEvent e) {
128+
public void update(@NotNull AnActionEvent e) {
129129
final Project project = e.getProject();
130130
if (project == null || project.isDefault()) {
131131
super.update(e);
@@ -159,7 +159,7 @@ public void update(AnActionEvent e) {
159159
}
160160

161161
@Nullable
162-
public static RunConfiguration findRunConfig(Project project) {
162+
public static RunConfiguration findRunConfig(@NotNull Project project) {
163163
// Look for a Flutter run config. If exactly one is found then return it otherwise return null.
164164
final RunManagerEx mgr = RunManagerEx.getInstanceEx(project);
165165
final List<RunConfiguration> configs = mgr.getAllConfigurationsList();
@@ -174,7 +174,7 @@ public static RunConfiguration findRunConfig(Project project) {
174174
return count == 1 ? sdkConfig : null;
175175
}
176176

177-
private static void onAttachTermination(@NotNull Project project, @NotNull Consumer<Project> runner) {
177+
private static void onAttachTermination(@NotNull Project project, @NotNull Consumer<@NotNull Project> runner) {
178178
final MessageBusConnection connection = project.getMessageBus().connect();
179179

180180
// Need an ExecutionListener to clean up project-scoped state when the Stop button is clicked.
@@ -221,7 +221,9 @@ private static class SelectConfigDialog extends DialogWrapper {
221221
"module was created. See <a href=\"" +
222222
FlutterConstants.URL_RUN_AND_DEBUG +
223223
"\">the Flutter documentation</a> for more information.</body></html>";
224+
//noinspection DataFlowIssue
224225
myTextPane.setText(selectConfig);
226+
//noinspection DataFlowIssue
225227
myPanel.add(myTextPane);
226228
init();
227229
//noinspection ConstantConditions

flutter-idea/src/io/flutter/actions/DeviceSelectorAction.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class DeviceSelectorAction extends ComboBoxAction implements DumbAware {
3535
private final List<AnAction> actions = new ArrayList<>();
3636
private final List<Project> knownProjects = Collections.synchronizedList(new ArrayList<>());
3737

38-
private SelectDeviceAction selectedDeviceAction;
38+
private @Nullable SelectDeviceAction selectedDeviceAction;
3939

4040
DeviceSelectorAction() {
4141
setSmallVariant(true);
@@ -73,24 +73,29 @@ public void update(@NotNull AnActionEvent e) {
7373
if (!knownProjects.contains(project)) {
7474
knownProjects.add(project);
7575
final Application application = ApplicationManager.getApplication();
76-
application.getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
77-
@Override
78-
public void projectClosed(@NotNull Project closedProject) {
79-
knownProjects.remove(closedProject);
80-
}
81-
});
76+
if (application != null) {
77+
application.getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
78+
@Override
79+
public void projectClosed(@NotNull Project closedProject) {
80+
knownProjects.remove(closedProject);
81+
}
82+
});
83+
}
8284
Runnable deviceListener = () -> queueUpdate(project, e.getPresentation());
8385
DeviceService.getInstance(project).addListener(deviceListener);
8486

8587
// Listen for android device changes, and rebuild the menu if necessary.
8688
Runnable emulatorListener = () -> queueUpdate(project, e.getPresentation());
8789
AndroidEmulatorManager.getInstance(project).addListener(emulatorListener);
88-
ProjectManager.getInstance().addProjectManagerListener(project, new ProjectManagerListener() {
89-
public void projectClosing(@NotNull Project project) {
90-
DeviceService.getInstance(project).removeListener(deviceListener);
91-
AndroidEmulatorManager.getInstance(project).removeListener(emulatorListener);
92-
}
93-
});
90+
var projectManager = ProjectManager.getInstance();
91+
if (projectManager != null) {
92+
projectManager.addProjectManagerListener(project, new ProjectManagerListener() {
93+
public void projectClosing(@NotNull Project project) {
94+
DeviceService.getInstance(project).removeListener(deviceListener);
95+
AndroidEmulatorManager.getInstance(project).removeListener(emulatorListener);
96+
}
97+
});
98+
}
9499
update(project, presentation);
95100
}
96101

@@ -139,9 +144,10 @@ private static void updateVisibility(final Project project, final @NotNull Prese
139144
final JComponent component = presentation.getClientProperty(new Key<>("customComponent"));
140145
if (component != null) {
141146
component.setVisible(visible);
142-
if (component.getParent() != null) {
143-
component.getParent().doLayout();
144-
component.getParent().repaint();
147+
var parent = component.getParent();
148+
if (parent != null) {
149+
parent.doLayout();
150+
parent.repaint();
145151
}
146152
}
147153
}
@@ -165,13 +171,16 @@ private void updateActions(@NotNull Project project, Presentation presentation)
165171
selectedDeviceAction = null;
166172

167173
for (FlutterDevice device : devices) {
174+
if (device == null) continue;
175+
168176
final SelectDeviceAction deviceAction = new SelectDeviceAction(device, devices);
169177
actions.add(deviceAction);
170178

171179
if (Objects.equals(device, selectedDevice)) {
172180
selectedDeviceAction = deviceAction;
173181

174182
final Presentation template = deviceAction.getTemplatePresentation();
183+
//noinspection DataFlowIssue
175184
presentation.setIcon(template.getIcon());
176185
//presentation.setText(deviceAction.presentationName());
177186
presentation.setEnabled(true);
@@ -196,15 +205,19 @@ private void updateActions(@NotNull Project project, Presentation presentation)
196205

197206
// Add Open Android emulators actions.
198207
final List<OpenEmulatorAction> emulatorActions = OpenEmulatorAction.getEmulatorActions(project);
199-
if (!emulatorActions.isEmpty()) {
208+
if (emulatorActions != null && !emulatorActions.isEmpty()) {
200209
actions.add(new Separator());
201210
actions.addAll(emulatorActions);
202211
}
203212
if (!FlutterModuleUtils.hasInternalDartSdkPath(project)) {
204213
actions.add(new Separator());
205214
actions.add(RestartFlutterDaemonAction.forDeviceSelector());
206215
}
207-
ActivityTracker.getInstance().inc();
216+
217+
var tracker = ActivityTracker.getInstance();
218+
if (tracker != null) {
219+
tracker.inc();
220+
}
208221
}
209222

210223
// Show the current device as selected when the combo box menu opens.
@@ -222,12 +235,12 @@ private static class SelectDeviceAction extends AnAction {
222235
this.device = device;
223236
}
224237

225-
public String presentationName() {
238+
public @NotNull String presentationName() {
226239
return device.presentationName();
227240
}
228241

229242
@Override
230-
public void actionPerformed(AnActionEvent e) {
243+
public void actionPerformed(@NotNull AnActionEvent e) {
231244
final Project project = e.getProject();
232245
final DeviceService service = project == null ? null : DeviceService.getInstance(project);
233246
if (service != null) {

flutter-idea/src/io/flutter/actions/ExtractWidgetAction.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@
3131

3232
public class ExtractWidgetAction extends DumbAwareAction {
3333
@Override
34-
public void actionPerformed(AnActionEvent event) {
34+
public void actionPerformed(@NotNull AnActionEvent event) {
3535
final DataContext dataContext = event.getDataContext();
36+
//noinspection DataFlowIssue
3637
final Project project = dataContext.getData(PlatformDataKeys.PROJECT);
38+
//noinspection DataFlowIssue
3739
final VirtualFile file = dataContext.getData(PlatformDataKeys.VIRTUAL_FILE);
40+
//noinspection DataFlowIssue
3841
final Editor editor = dataContext.getData(PlatformDataKeys.EDITOR);
42+
//noinspection DataFlowIssue
3943
final Caret caret = dataContext.getData(PlatformDataKeys.CARET);
4044

4145
if (project != null && file != null && editor != null && caret != null) {
@@ -51,7 +55,9 @@ public void actionPerformed(AnActionEvent event) {
5155
if (initialStatus.hasError()) {
5256
final String message = initialStatus.getMessage();
5357
assert message != null;
54-
CommonRefactoringUtil.showErrorHint(project, editor, message, CommonBundle.getErrorTitle(), null);
58+
String title = CommonBundle.getErrorTitle();
59+
assert title != null;
60+
CommonRefactoringUtil.showErrorHint(project, editor, message, title, null);
5561
return;
5662
}
5763

@@ -60,7 +66,7 @@ public void actionPerformed(AnActionEvent event) {
6066
}
6167

6268
@Override
63-
public void update(AnActionEvent e) {
69+
public void update(@NotNull AnActionEvent e) {
6470
e.getPresentation().setVisible(isVisibleFor(e));
6571
super.update(e);
6672
}
@@ -70,17 +76,17 @@ public void update(AnActionEvent e) {
7076
return ActionUpdateThread.BGT;
7177
}
7278

73-
protected static boolean isVisibleFor(AnActionEvent e) {
79+
protected static boolean isVisibleFor(@NotNull AnActionEvent e) {
7480
final DataContext dataContext = e.getDataContext();
75-
final Project project = dataContext.getData(PlatformDataKeys.PROJECT);
81+
//noinspection DataFlowIssue
7682
final VirtualFile file = dataContext.getData(PlatformDataKeys.VIRTUAL_FILE);
7783
return file != null && FlutterUtils.isDartFile(file);
7884
}
7985
}
8086

8187
class ExtractWidgetDialog extends ServerRefactoringDialog<ExtractWidgetRefactoring> {
82-
@NotNull final ExtractWidgetRefactoring myRefactoring;
83-
private final JTextField myNameField = new JTextField();
88+
final @NotNull ExtractWidgetRefactoring myRefactoring;
89+
private final @NotNull JTextField myNameField = new JTextField();
8490

8591
public ExtractWidgetDialog(@NotNull Project project,
8692
@Nullable Editor editor,
@@ -92,17 +98,21 @@ public ExtractWidgetDialog(@NotNull Project project,
9298

9399
myNameField.setText("NewWidget");
94100
myNameField.selectAll();
95-
myNameField.getDocument().addDocumentListener(new DocumentAdapter() {
96-
@Override
97-
protected void textChanged(@NotNull DocumentEvent event) {
98-
updateRefactoringOptions();
99-
}
100-
});
101+
var document = myNameField.getDocument();
102+
if (document != null) {
103+
document.addDocumentListener(new DocumentAdapter() {
104+
@Override
105+
protected void textChanged(@NotNull DocumentEvent event) {
106+
updateRefactoringOptions();
107+
}
108+
});
109+
}
101110

102111
updateRefactoringOptions();
103112
}
104113

105114
private void updateRefactoringOptions() {
115+
//noinspection DataFlowIssue
106116
myRefactoring.setName(myNameField.getText());
107117
myRefactoring.sendOptions();
108118
}
@@ -137,6 +147,7 @@ protected JComponent createNorthPanel() {
137147
gbConstraints.fill = GridBagConstraints.BOTH;
138148
gbConstraints.anchor = GridBagConstraints.WEST;
139149
panel.add(myNameField, gbConstraints);
150+
//noinspection DataFlowIssue
140151
myNameField.setPreferredSize(new Dimension(200, myNameField.getPreferredSize().height));
141152

142153
return panel;

flutter-idea/src/io/flutter/actions/FlutterBuildActionGroup.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
2424
import org.jetbrains.annotations.NotNull;
2525
import org.jetbrains.annotations.Nullable;
2626

27-
import java.util.List;
28-
2927
public class FlutterBuildActionGroup extends DefaultActionGroup {
3028

3129
public static void build(@NotNull Project project,
32-
@NotNull PubRoot pubRoot,
33-
@NotNull FlutterSdk sdk,
34-
@NotNull BuildType buildType,
35-
@Nullable String desc) {
30+
@NotNull PubRoot pubRoot,
31+
@NotNull FlutterSdk sdk,
32+
@NotNull BuildType buildType,
33+
@Nullable String desc) {
3634
final ProgressHelper progressHelper = new ProgressHelper(project);
3735
progressHelper.start(desc == null ? "building" : desc);
3836
ProcessAdapter processAdapter = new ProcessAdapter() {
@@ -105,7 +103,12 @@ public static Module findFlutterModule(@NotNull Project project, @NotNull Virtua
105103
return module;
106104
}
107105
// We may get here if the file is in the Android module of a Flutter module project.
108-
final VirtualFile parent = OpenApiUtils.getContentRoots(module)[0].getParent();
106+
var root = OpenApiUtils.getContentRoots(module)[0];
107+
if (root == null) return null;
108+
109+
final VirtualFile parent = root.getParent();
110+
if (parent == null) return null;
111+
109112
module = ModuleUtilCore.findModuleForFile(parent, project);
110113
if (module == null) {
111114
return null;
@@ -135,7 +138,7 @@ public void actionPerformed(@NotNull AnActionEvent event) {
135138
build(project, pubRoot, sdk, buildType, presentation.getDescription());
136139
}
137140
else {
138-
List<PubRoot> roots = PubRoots.forProject(project);
141+
var roots = PubRoots.forProject(project);
139142
for (PubRoot sub : roots) {
140143
build(project, sub, sdk, buildType, presentation.getDescription());
141144
}

flutter-idea/src/io/flutter/actions/FlutterExternalIdeActionGroup.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
* See https://github.com/flutter/flutter-intellij/issues/7103
1919
*/
2020
public class FlutterExternalIdeActionGroup extends DefaultActionGroup {
21-
private static boolean isExternalIdeFile(AnActionEvent e) {
22-
final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
21+
private static boolean isExternalIdeFile(@NotNull AnActionEvent e) {
22+
@SuppressWarnings("DataFlowIssue") final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
2323
if (file == null || !file.exists()) {
2424
return false;
2525
}
@@ -86,7 +86,7 @@ private static boolean isProjectDirectory(@NotNull VirtualFile file, @Nullable P
8686
}
8787

8888
@Override
89-
public void update(AnActionEvent event) {
89+
public void update(@NotNull AnActionEvent event) {
9090
final Presentation presentation = event.getPresentation();
9191
final boolean enabled = isExternalIdeFile(event);
9292
presentation.setEnabled(enabled);

flutter-idea/src/io/flutter/actions/FlutterPackagesExplorerActionGroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
public class FlutterPackagesExplorerActionGroup extends DefaultActionGroup {
1515

1616
private static boolean isFlutterPubspec(@NotNull AnActionEvent e) {
17-
final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
17+
@SuppressWarnings("DataFlowIssue") final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
1818
final PubRoot root = file == null ? null : PubRoot.forDirectory(file.getParent());
1919
return root != null && root.getPubspec().equals(file) && root.declaresFlutter();
2020
}

flutter-idea/src/io/flutter/actions/FlutterRetargetAppAction.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class FlutterRetargetAppAction extends DumbAwareAction {
3333
FlutterRetargetAppAction(@NotNull String actionId,
3434
@Nullable String text,
3535
@Nullable String description,
36-
@SuppressWarnings("SameParameterValue") @NotNull String... places) {
36+
@SuppressWarnings("SameParameterValue") @NotNull String @NotNull ... places) {
3737
super(text, description, null);
3838
myActionId = actionId;
3939
myPlaces.addAll(Arrays.asList(places));
@@ -44,15 +44,15 @@ public abstract class FlutterRetargetAppAction extends DumbAwareAction {
4444
}
4545

4646
@Override
47-
public void actionPerformed(AnActionEvent e) {
47+
public void actionPerformed(@NotNull AnActionEvent e) {
4848
final AnAction action = getAction(e.getProject());
4949
if (action != null) {
5050
action.actionPerformed(e);
5151
}
5252
}
5353

5454
@Override
55-
public void update(AnActionEvent e) {
55+
public void update(@NotNull AnActionEvent e) {
5656
final Presentation presentation = e.getPresentation();
5757

5858
final Project project = e.getProject();
@@ -76,7 +76,7 @@ public void update(AnActionEvent e) {
7676
}
7777
}
7878

79-
private AnAction getAction(@Nullable Project project) {
79+
private @Nullable AnAction getAction(@Nullable Project project) {
8080
return project == null ? null : ProjectActions.getAction(project, myActionId);
8181
}
8282
}

flutter-idea/src/io/flutter/actions/FlutterSdkAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public boolean enableActionInBazelContext() {
8282
return false;
8383
}
8484

85-
public static void showMissingSdkDialog(Project project) {
85+
public static void showMissingSdkDialog(@Nullable Project project) {
8686
final int response = FlutterMessages.showDialog(project, FlutterBundle.message("flutter.sdk.notAvailable.message"),
8787
FlutterBundle.message("flutter.sdk.notAvailable.title"),
8888
new String[]{"Yes, configure", "No, thanks"}, -1);

flutter-idea/src/io/flutter/actions/OpenEmulatorAction.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.List;
18+
import java.util.Objects;
1819

1920
import static java.util.stream.Collectors.toList;
2021

@@ -33,12 +34,12 @@ public static List<OpenEmulatorAction> getEmulatorActions(Project project) {
3334
final AndroidEmulatorManager emulatorManager = AndroidEmulatorManager.getInstance(project);
3435

3536
final List<AndroidEmulator> emulators = emulatorManager.getCachedEmulators();
36-
return emulators.stream().map(OpenEmulatorAction::new).collect(toList());
37+
return emulators.stream().filter(Objects::nonNull).map(OpenEmulatorAction::new).collect(toList());
3738
}
3839

39-
final AndroidEmulator emulator;
40+
final @NotNull AndroidEmulator emulator;
4041

41-
public OpenEmulatorAction(AndroidEmulator emulator) {
42+
public OpenEmulatorAction(@NotNull AndroidEmulator emulator) {
4243
super("Open Android Emulator: " + emulator.getName());
4344

4445
this.emulator = emulator;

0 commit comments

Comments
 (0)