Skip to content

Commit b9cd748

Browse files
authored
[CQ] make FlutterSdk null-safe (#8063)
`FlutterSdk` is referenced in many places so a little bit of null-awareness goes a long way. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
1 parent 3594875 commit b9cd748

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

flutter-idea/src/io/flutter/run/SdkFields.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public SdkFields() {
5353
/**
5454
* Creates SDK fields from a Dart file containing a main method.
5555
*/
56-
public SdkFields(VirtualFile launchFile) {
56+
public SdkFields(@NotNull VirtualFile launchFile) {
5757
filePath = launchFile.getPath();
5858
}
5959

flutter-idea/src/io/flutter/sdk/FlutterCreateAdditionalSettings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public void setKotlin(boolean value) {
9797
kotlin = value;
9898
}
9999

100+
@NotNull
100101
@NonNls
101102
public List<String> getArgs() {
102103
final List<String> args = new ArrayList<>();

flutter-idea/src/io/flutter/sdk/FlutterSdk.java

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,22 @@
5353
import static java.util.Arrays.asList;
5454

5555
public class FlutterSdk {
56-
public static final String FLUTTER_SDK_GLOBAL_LIB_NAME = "Flutter SDK";
56+
public static final @NotNull String FLUTTER_SDK_GLOBAL_LIB_NAME = "Flutter SDK";
5757

58-
public static final String DART_SDK_SUFFIX = "/bin/cache/dart-sdk";
59-
public static final String LINUX_DART_SUFFIX = "/google-dartlang";
60-
public static final String LOCAL_DART_SUFFIX = "/google-dartlang-local";
61-
public static final String MAC_DART_SUFFIX = "/dart_lang/macos_sdk";
58+
public static final @NotNull String DART_SDK_SUFFIX = "/bin/cache/dart-sdk";
59+
public static final @NotNull String LINUX_DART_SUFFIX = "/google-dartlang";
60+
public static final @NotNull String LOCAL_DART_SUFFIX = "/google-dartlang-local";
61+
public static final @NotNull String MAC_DART_SUFFIX = "/dart_lang/macos_sdk";
6262

63-
private static final String DART_CORE_SUFFIX = DART_SDK_SUFFIX + "/lib/core";
63+
private static final @NotNull String DART_CORE_SUFFIX = DART_SDK_SUFFIX + "/lib/core";
6464

65-
private static final Logger LOG = Logger.getInstance(FlutterSdk.class);
65+
private static final @NotNull Logger LOG = Logger.getInstance(FlutterSdk.class);
6666

67-
private static final Map<String, FlutterSdk> projectSdkCache = new HashMap<>();
67+
private static final @NotNull Map<String, FlutterSdk> projectSdkCache = new HashMap<>();
6868

6969
private final @NotNull VirtualFile myHome;
7070
private final @NotNull FlutterSdkVersion myVersion;
71-
private final Map<String, String> cachedConfigValues = new HashMap<>();
71+
private final @NotNull Map<String, String> cachedConfigValues = new HashMap<>();
7272

7373
private FlutterSdk(@NotNull final VirtualFile home, @NotNull final FlutterSdkVersion version) {
7474
myHome = home;
@@ -146,32 +146,35 @@ public static FlutterSdk forPath(@NotNull final String path) {
146146
}
147147

148148
@NotNull
149-
private static FlutterSdk saveSdkInCache(VirtualFile home) {
149+
private static FlutterSdk saveSdkInCache(@NotNull VirtualFile home) {
150150
final String cacheKey = home.getCanonicalPath();
151151
synchronized (projectSdkCache) {
152152
if (!projectSdkCache.containsKey(cacheKey)) {
153153
projectSdkCache.put(cacheKey, new FlutterSdk(home, FlutterSdkVersion.readFromSdk(home)));
154154
}
155155
}
156-
return projectSdkCache.get(cacheKey);
156+
return Objects.requireNonNull(projectSdkCache.get(cacheKey));
157157
}
158158

159159
@Nullable
160160
private static Library getDartSdkLibrary(@NotNull Project project) {
161-
final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(project);
161+
LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
162+
if (registrar == null) return null;
163+
final LibraryTable libraryTable = registrar.getLibraryTable(project);
162164
for (Library lib : libraryTable.getLibraries()) {
163-
if ("Dart SDK".equals(lib.getName())) {
165+
if (lib != null && "Dart SDK".equals(lib.getName())) {
164166
return lib;
165167
}
166168
}
167169
return null;
168170
}
169171

170172
@Nullable
171-
private static FlutterSdk getFlutterFromDartSdkLibrary(Library lib) {
173+
private static FlutterSdk getFlutterFromDartSdkLibrary(@NotNull Library lib) {
174+
assert OrderRootType.CLASSES != null;
172175
final String[] urls = lib.getUrls(OrderRootType.CLASSES);
173176
for (String url : urls) {
174-
if (url.endsWith(DART_CORE_SUFFIX)) {
177+
if (url != null && url.endsWith(DART_CORE_SUFFIX)) {
175178
final String flutterUrl = url.substring(0, url.length() - DART_CORE_SUFFIX.length());
176179
final VirtualFile home = VirtualFileManager.getInstance().findFileByUrl(flutterUrl);
177180
return home == null ? null : saveSdkInCache(home);
@@ -180,6 +183,7 @@ private static FlutterSdk getFlutterFromDartSdkLibrary(Library lib) {
180183
return null;
181184
}
182185

186+
@NotNull
183187
public FlutterCommand flutterVersion() {
184188
// TODO(devoncarew): Switch to calling 'flutter --version --machine'. The ouput will look like:
185189
// Building flutter tool...
@@ -196,19 +200,23 @@ public FlutterCommand flutterVersion() {
196200
return new FlutterCommand(this, getHome(), FlutterCommand.Type.VERSION);
197201
}
198202

203+
@NotNull
199204
public FlutterCommand flutterUpgrade() {
200205
return new FlutterCommand(this, getHome(), FlutterCommand.Type.UPGRADE);
201206
}
202207

208+
@NotNull
203209
public FlutterCommand flutterClean(@NotNull PubRoot root) {
204210
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.CLEAN);
205211
}
206212

213+
@NotNull
207214
public FlutterCommand flutterDoctor() {
208215
return new FlutterCommand(this, getHome(), FlutterCommand.Type.DOCTOR);
209216
}
210217

211218
@NonNls
219+
@NotNull
212220
public FlutterCommand flutterCreate(@NotNull VirtualFile appDir, @Nullable FlutterCreateAdditionalSettings additionalSettings) {
213221
final List<String> args = new ArrayList<>();
214222
if (additionalSettings != null) {
@@ -236,39 +244,48 @@ public FlutterCommand flutterCreate(@NotNull VirtualFile appDir, @Nullable Flutt
236244
return new FlutterCommand(this, appDir.getParent(), FlutterCommand.Type.CREATE, vargs);
237245
}
238246

247+
@NotNull
239248
public FlutterCommand flutterPackagesAdd(@NotNull PubRoot root, @NotNull String name, boolean devOnly) {
240249
if (devOnly) name = "dev:" + name;
241250
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.PUB_ADD, name);
242251
}
243252

253+
@NotNull
244254
public FlutterCommand flutterPackagesGet(@NotNull PubRoot root) {
245255
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.PUB_GET);
246256
}
247257

258+
@NotNull
248259
public FlutterCommand flutterPackagesUpgrade(@NotNull PubRoot root) {
249260
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.PUB_UPGRADE);
250261
}
251262

263+
@NotNull
252264
public FlutterCommand flutterPackagesOutdated(@NotNull PubRoot root) {
253265
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.PUB_OUTDATED);
254266
}
255267

268+
@NotNull
256269
public FlutterCommand flutterPub(@Nullable PubRoot root, String... args) {
257270
return new FlutterCommand(this, root == null ? null : root.getRoot(), FlutterCommand.Type.PUB, args);
258271
}
259272

273+
@NotNull
260274
public FlutterCommand flutterBuild(@NotNull PubRoot root, String... additionalArgs) {
261275
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.BUILD, additionalArgs);
262276
}
263277

278+
@NotNull
264279
public FlutterCommand flutterConfig(String... additionalArgs) {
265280
return new FlutterCommand(this, getHome(), FlutterCommand.Type.CONFIG, additionalArgs);
266281
}
267282

283+
@NotNull
268284
public FlutterCommand flutterChannel() {
269285
return new FlutterCommand(this, getHome(), FlutterCommand.Type.CHANNEL);
270286
}
271287

288+
@NotNull
272289
public FlutterCommand flutterRun(@NotNull PubRoot root,
273290
@NotNull VirtualFile main,
274291
@NotNull FlutterDevice device,
@@ -278,7 +295,8 @@ public FlutterCommand flutterRun(@NotNull PubRoot root,
278295
String... additionalArgs) {
279296
final List<String> args = new ArrayList<>();
280297
args.add("--machine");
281-
if (FlutterSettings.getInstance().isVerboseLogging()) {
298+
FlutterSettings settings = FlutterSettings.getInstance();
299+
if (settings != null && settings.isVerboseLogging()) {
282300
args.add("--verbose");
283301
}
284302

@@ -316,6 +334,7 @@ else if (flutterLaunchMode == FlutterLaunchMode.RELEASE) {
316334
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.RUN, args.toArray(new String[]{ }));
317335
}
318336

337+
@NotNull
319338
public FlutterCommand flutterAttach(@NotNull PubRoot root, @NotNull VirtualFile main, @Nullable FlutterDevice device,
320339
@NotNull FlutterLaunchMode flutterLaunchMode, String... additionalArgs) {
321340
final List<String> args = new ArrayList<>();
@@ -349,6 +368,7 @@ else if (flutterLaunchMode == FlutterLaunchMode.RELEASE) {
349368
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.ATTACH, args.toArray(new String[]{ }));
350369
}
351370

371+
@NotNull
352372
public FlutterCommand flutterRunOnTester(@NotNull PubRoot root, @NotNull String mainPath) {
353373
final List<String> args = new ArrayList<>();
354374
args.add("--machine");
@@ -357,6 +377,7 @@ public FlutterCommand flutterRunOnTester(@NotNull PubRoot root, @NotNull String
357377
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.RUN, args.toArray(new String[]{ }));
358378
}
359379

380+
@NotNull
360381
public FlutterCommand flutterTest(@NotNull PubRoot root, @NotNull VirtualFile fileOrDir, @Nullable String testNameSubstring,
361382
@NotNull RunMode mode, @Nullable String additionalArgs, TestFields.Scope scope, boolean useRegexp) {
362383

@@ -453,6 +474,7 @@ public PubRoot createFiles(@NotNull VirtualFile baseDir, @Nullable Module module
453474
* <p>
454475
* Returns the process if successfully started.
455476
*/
477+
@Nullable
456478
public Process startPubAdd(@NotNull PubRoot root, @NotNull Project project, @NotNull String pkg, boolean devOnly) {
457479
final Module module = root.getModule(project);
458480
if (module == null) return null;
@@ -469,6 +491,7 @@ public Process startPubAdd(@NotNull PubRoot root, @NotNull Project project, @Not
469491
* <p>
470492
* Returns the process if successfully started.
471493
*/
494+
@Nullable
472495
public Process startPubGet(@NotNull PubRoot root, @NotNull Project project) {
473496
final Module module = root.getModule(project);
474497
if (module == null) return null;
@@ -485,6 +508,7 @@ public Process startPubGet(@NotNull PubRoot root, @NotNull Project project) {
485508
* <p>
486509
* Returns the process if successfully started.
487510
*/
511+
@Nullable
488512
public Process startPubUpgrade(@NotNull PubRoot root, @NotNull Project project) {
489513
final Module module = root.getModule(project);
490514
if (module == null) return null;
@@ -500,6 +524,7 @@ public Process startPubUpgrade(@NotNull PubRoot root, @NotNull Project project)
500524
* <p>
501525
* Returns the process if successfully started.
502526
*/
527+
@Nullable
503528
public Process startPubOutdated(@NotNull PubRoot root, @NotNull Project project) {
504529
final Module module = root.getModule(project);
505530
if (module == null) return null;
@@ -565,8 +590,9 @@ public FlutterSdkChannel queryFlutterChannel(boolean useCachedValue) {
565590
return FlutterSdkChannel.fromText(branch);
566591
}
567592

593+
@NotNull
568594
@NonNls
569-
private static final String[] PLATFORMS =
595+
private static final String @NotNull [] PLATFORMS =
570596
new String[]{"enable-android", "enable-ios", "enable-web", "enable-linux-desktop", "enable-macos-desktop", "enable-windows-desktop"};
571597

572598
@NotNull
@@ -599,12 +625,14 @@ else if ("false".equals(value)) {
599625
}
600626
try {
601627
final JsonElement elem = JsonUtils.parseString(stdout.substring(startJsonIndex));
602-
if (elem.isJsonNull()) {
628+
if (elem == null || elem.isJsonNull()) {
603629
FlutterUtils.warn(LOG, FlutterBundle.message("flutter.sdk.invalid.json.error"));
604630
return platforms;
605631
}
606632

607633
final JsonObject obj = elem.getAsJsonObject();
634+
if (obj == null) return platforms;
635+
608636
for (String key : PLATFORMS) {
609637
final JsonPrimitive primitive = obj.getAsJsonPrimitive(key);
610638
if (primitive != null) {
@@ -636,12 +664,14 @@ public String queryFlutterConfig(String key, boolean useCachedValue) {
636664
if (stdout != null) {
637665
try {
638666
final JsonElement elem = JsonUtils.parseString(stdout.substring(stdout.indexOf('{')));
639-
if (elem.isJsonNull()) {
667+
if (elem == null || elem.isJsonNull()) {
640668
FlutterUtils.warn(LOG, FlutterBundle.message("flutter.sdk.invalid.json.error"));
641669
return null;
642670
}
643671

644672
final JsonObject obj = elem.getAsJsonObject();
673+
if (obj == null) return null;
674+
645675
for (String jsonKey : JsonUtils.getKeySet(obj)) {
646676
final JsonElement element = obj.get(jsonKey);
647677
if (element == null || element.isJsonNull()) {

0 commit comments

Comments
 (0)