Fix flutter doctor (pluginsPath) check for Mac (#50324)

diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index da35d54..f5a8a2c 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -4,6 +4,8 @@
 
 import 'dart:async';
 
+import 'package:meta/meta.dart';
+
 import 'android/android_studio_validator.dart';
 import 'android/android_workflow.dart';
 import 'artifacts.dart';
@@ -699,19 +701,23 @@
   Future<ValidationResult> validate() async {
     final List<ValidationMessage> messages = <ValidationMessage>[];
 
-    messages.add(ValidationMessage(userMessages.intellijLocation(installPath)));
+    if (pluginsPath == null) {
+      messages.add(ValidationMessage.error('Invalid IntelliJ version number.'));
+    } else {
+      messages.add(ValidationMessage(userMessages.intellijLocation(installPath)));
 
-    final IntelliJPlugins plugins = IntelliJPlugins(pluginsPath);
-    plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'],
-        'Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
-    plugins.validatePackage(messages, <String>['Dart'], 'Dart');
+      final IntelliJPlugins plugins = IntelliJPlugins(pluginsPath);
+      plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'],
+          'Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
+      plugins.validatePackage(messages, <String>['Dart'], 'Dart');
 
-    if (_hasIssues(messages)) {
-      messages.add(ValidationMessage(userMessages.intellijPluginInfo));
+      if (_hasIssues(messages)) {
+        messages.add(ValidationMessage(userMessages.intellijPluginInfo));
+      }
+
+      _validateIntelliJVersion(messages, kMinIdeaVersion);
     }
 
-    _validateIntelliJVersion(messages, kMinIdeaVersion);
-
     return ValidationResult(
       _hasIssues(messages) ? ValidationType.partial : ValidationType.installed,
       messages,
@@ -847,31 +853,53 @@
     return validators;
   }
 
+  @visibleForTesting
+  String get plistFile {
+    _plistFile ??= globals.fs.path.join(installPath, 'Contents', 'Info.plist');
+    return _plistFile;
+  }
+  String _plistFile;
+
   @override
   String get version {
-    if (_version == null) {
-      final String plistFile = globals.fs.path.join(installPath, 'Contents', 'Info.plist');
-      _version = PlistParser.instance.getValueFromFile(
+    _version ??= PlistParser.instance.getValueFromFile(
         plistFile,
         PlistParser.kCFBundleShortVersionStringKey,
       ) ?? 'unknown';
-    }
     return _version;
   }
   String _version;
 
   @override
   String get pluginsPath {
+    if (_pluginsPath != null) {
+      return _pluginsPath;
+    }
+
+    final String altLocation = PlistParser.instance.getValueFromFile(plistFile, 'JetBrainsToolboxApp');
+
+    if (altLocation != null) {
+      _pluginsPath = altLocation + '.plugins';
+      return _pluginsPath;
+    }
+
     final List<String> split = version.split('.');
+
+    if (split.length < 2) {
+      return null;
+    }
+
     final String major = split[0];
     final String minor = split[1];
-    return globals.fs.path.join(
+    _pluginsPath = globals.fs.path.join(
       globals.fsUtils.homeDirPath,
       'Library',
       'Application Support',
       '$id$major.$minor',
     );
+    return _pluginsPath;
   }
+  String _pluginsPath;
 }
 
 class DeviceValidator extends DoctorValidator {
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
index a6ec89b..b8b253b 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
@@ -13,6 +13,7 @@
 import 'package:flutter_tools/src/doctor.dart';
 import 'package:flutter_tools/src/features.dart';
 import 'package:flutter_tools/src/globals.dart' as globals;
+import 'package:flutter_tools/src/ios/plist_parser.dart';
 import 'package:flutter_tools/src/proxy_validator.dart';
 import 'package:flutter_tools/src/reporting/reporting.dart';
 import 'package:flutter_tools/src/vscode/vscode.dart';
@@ -67,6 +68,19 @@
       expect(message.message, contains('recommended minimum version'));
     }, overrides: noColorTerminalOverride);
 
+    testUsingContext('intellij plugins path checking on mac', () async {
+      final String pathViaToolbox = globals.fs.path.join('test', 'data', 'intellij', 'mac_via_toolbox');
+      final String pathNotViaToolbox = globals.fs.path.join('test', 'data', 'intellij', 'mac_not_via_toolbox');
+
+      final IntelliJValidatorOnMac validatorViaToolbox = IntelliJValidatorOnMac('Test', 'Test', pathViaToolbox);
+      expect(validatorViaToolbox.plistFile, 'test/data/intellij/mac_via_toolbox/Contents/Info.plist');
+
+      final IntelliJValidatorOnMac validatorNotViaToolbox = IntelliJValidatorOnMac('Test', 'Test', pathNotViaToolbox);
+      expect(validatorNotViaToolbox.plistFile, 'test/data/intellij/mac_not_via_toolbox/Contents/Info.plist');
+    }, overrides: <Type, Generator>{
+      PlistParser: () => const PlistParser(),
+    });
+
     testUsingContext('vs code validator when both installed', () async {
       final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension.validate();
       expect(result.type, ValidationType.installed);
diff --git a/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist b/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist
new file mode 100644
index 0000000..087127f
--- /dev/null
+++ b/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC '-//Apple Computer//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>
+<plist version="1.0">
+ <dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>English</string>
+  <key>CFBundleExecutable</key>
+  <string>jetbrains-toolbox-launcher</string>
+  <key>CFBundleGetInfoString</key>
+  <string/>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundlePackageType</key>
+  <string>APPL</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>NSHumanReadableCopyright</key>
+  <string>Copyright (c) JetBrains s.r.o.</string>
+  <key>NSHighResolutionCapable</key>
+  <true/>
+  <key>NSUIElement</key>
+  <false/>
+  <key>LSUIElement</key>
+  <true/>
+  <key>CFBundleName</key>
+  <string>IntelliJ IDEA Ultimate 2019.3.3</string>
+  <key>CFBundleIdentifier</key>
+  <string>com.jetbrains.apps.activator.linkapp.pcom.jetbrains.apps.activator__ntelli_ltimate_2019_3_3</string>
+  <key>CFBundleVersion</key>
+  <string>2019.3.3</string>
+  <key>CFBundleLongVersionString</key>
+  <string>2019.3.3</string>
+  <key>CFBundleShortVersionString</key>
+  <string>2019.3.3</string>
+  <key>CFBundleIconFile</key>
+  <string>icon.icns</string>
+ </dict>
+</plist>
diff --git a/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist b/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist
new file mode 100644
index 0000000..0700e06
--- /dev/null
+++ b/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC '-//Apple Computer//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>
+<plist version="1.0">
+ <dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>English</string>
+  <key>CFBundleExecutable</key>
+  <string>jetbrains-toolbox-launcher</string>
+  <key>CFBundleGetInfoString</key>
+  <string/>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundlePackageType</key>
+  <string>APPL</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>NSHumanReadableCopyright</key>
+  <string>Copyright (c) JetBrains s.r.o.</string>
+  <key>NSHighResolutionCapable</key>
+  <true/>
+  <key>NSUIElement</key>
+  <false/>
+  <key>LSUIElement</key>
+  <true/>
+  <key>CFBundleName</key>
+  <string>IntelliJ IDEA Ultimate 2019.3.3</string>
+  <key>CFBundleIdentifier</key>
+  <string>com.jetbrains.apps.activator.linkapp.pcom.jetbrains.apps.activator__ntelli_ltimate_2019_3_3</string>
+  <key>CFBundleVersion</key>
+  <string>2019.3.3</string>
+  <key>CFBundleLongVersionString</key>
+  <string>2019.3.3</string>
+  <key>CFBundleShortVersionString</key>
+  <string>2019.3.3</string>
+  <key>CFBundleIconFile</key>
+  <string>icon.icns</string>
+  <key>JetBrainsToolboxApp</key>
+  <string>/Users/lynn/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.6494.35/IntelliJ IDEA.app</string>
+ </dict>
+</plist>