182 lines
5.4 KiB
C#
182 lines
5.4 KiB
C#
|
/*---------------------------------------------------------------------------------------------
|
|||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|||
|
*--------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
#if UNITY_EDITOR_OSX
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.IO;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using Unity.CodeEditor;
|
|||
|
using IOPath = System.IO.Path;
|
|||
|
|
|||
|
namespace Microsoft.Unity.VisualStudio.Editor
|
|||
|
{
|
|||
|
internal class VisualStudioForMacInstallation : VisualStudioInstallation
|
|||
|
{
|
|||
|
// C# language version support for Visual Studio for Mac
|
|||
|
private static readonly VersionPair[] OSXVersionTable =
|
|||
|
{
|
|||
|
// VisualStudio for Mac 2022
|
|||
|
new VersionPair(17,4, /* => */ 11,0),
|
|||
|
new VersionPair(17,0, /* => */ 10,0),
|
|||
|
|
|||
|
// VisualStudio for Mac 8.x
|
|||
|
new VersionPair(8,8, /* => */ 9,0),
|
|||
|
new VersionPair(8,3, /* => */ 8,0),
|
|||
|
new VersionPair(8,0, /* => */ 7,3),
|
|||
|
};
|
|||
|
|
|||
|
private static readonly IGenerator _generator = new LegacyStyleProjectGeneration();
|
|||
|
|
|||
|
public override bool SupportsAnalyzers
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return Version >= new Version(8, 3);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override Version LatestLanguageVersionSupported
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return GetLatestLanguageVersionSupported(OSXVersionTable);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private string GetExtensionPath()
|
|||
|
{
|
|||
|
const string addinName = "MonoDevelop.Unity";
|
|||
|
const string addinAssembly = addinName + ".dll";
|
|||
|
|
|||
|
// user addins repository
|
|||
|
var localAddins = IOPath.Combine(
|
|||
|
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
|
|||
|
$"Library/Application Support/VisualStudio/${Version.Major}.0" + "/LocalInstall/Addins");
|
|||
|
|
|||
|
// In the user addins repository, the addins are suffixed by their versions, like `MonoDevelop.Unity.1.0`
|
|||
|
// When installing another local user addin, MD will remove files inside the folder
|
|||
|
// So we browse all VSTUM addins, and return the one with an addin assembly
|
|||
|
if (Directory.Exists(localAddins))
|
|||
|
{
|
|||
|
foreach (var folder in Directory.GetDirectories(localAddins, addinName + "*", SearchOption.TopDirectoryOnly))
|
|||
|
{
|
|||
|
if (File.Exists(IOPath.Combine(folder, addinAssembly)))
|
|||
|
return folder;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Check in Visual Studio.app/
|
|||
|
// In that case the name of the addin is used
|
|||
|
var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}");
|
|||
|
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
|
|||
|
return addinPath;
|
|||
|
|
|||
|
addinPath = IOPath.Combine(Path, $"Contents/MonoBundle/Addins/{addinName}");
|
|||
|
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
|
|||
|
return addinPath;
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
public override string[] GetAnalyzers()
|
|||
|
{
|
|||
|
var vstuPath = GetExtensionPath();
|
|||
|
if (string.IsNullOrEmpty(vstuPath))
|
|||
|
return Array.Empty<string>();
|
|||
|
|
|||
|
return GetAnalyzers(vstuPath);
|
|||
|
}
|
|||
|
|
|||
|
public override IGenerator ProjectGenerator
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return _generator;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static bool IsCandidateForDiscovery(string path)
|
|||
|
{
|
|||
|
return Directory.Exists(path) && Regex.IsMatch(path, "Visual\\s?Studio(?!.*Code.*).*.app$", RegexOptions.IgnoreCase);
|
|||
|
}
|
|||
|
|
|||
|
public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation)
|
|||
|
{
|
|||
|
installation = null;
|
|||
|
|
|||
|
if (string.IsNullOrEmpty(editorPath))
|
|||
|
return false;
|
|||
|
|
|||
|
if (!IsCandidateForDiscovery(editorPath))
|
|||
|
return false;
|
|||
|
|
|||
|
// On Mac we use the .app folder, so we need to access to main assembly
|
|||
|
var fvi = IOPath.Combine(editorPath, "Contents/Resources/lib/monodevelop/bin/VisualStudio.exe");
|
|||
|
|
|||
|
if (!File.Exists(fvi))
|
|||
|
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.exe");
|
|||
|
|
|||
|
if (!File.Exists(fvi))
|
|||
|
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.dll");
|
|||
|
|
|||
|
if (!File.Exists(fvi))
|
|||
|
return false;
|
|||
|
|
|||
|
// VS preview are not using the isPrerelease flag so far
|
|||
|
// On Windows FileDescription contains "Preview", but not on Mac
|
|||
|
var vi = FileVersionInfo.GetVersionInfo(fvi);
|
|||
|
var version = new Version(vi.ProductVersion);
|
|||
|
var isPrerelease = vi.IsPreRelease || string.Concat(editorPath, "/" + vi.FileDescription).ToLower().Contains("preview");
|
|||
|
|
|||
|
installation = new VisualStudioForMacInstallation()
|
|||
|
{
|
|||
|
IsPrerelease = isPrerelease,
|
|||
|
Name = $"{vi.FileDescription}{(isPrerelease ? " Preview" : string.Empty)} [{version.ToString(3)}]",
|
|||
|
Path = editorPath,
|
|||
|
Version = version
|
|||
|
};
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
|||
|
{
|
|||
|
var candidates = Directory.EnumerateDirectories("/Applications", "*.app");
|
|||
|
foreach (var candidate in candidates)
|
|||
|
{
|
|||
|
if (TryDiscoverInstallation(candidate, out var installation))
|
|||
|
yield return installation;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[DllImport("AppleEventIntegration")]
|
|||
|
private static extern bool OpenVisualStudio(string appPath, string solutionPath, string filePath, int line);
|
|||
|
|
|||
|
public override void CreateExtraFiles(string projectDirectory)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public override bool Open(string path, int line, int column, string solution)
|
|||
|
{
|
|||
|
string absolutePath = "";
|
|||
|
if (!string.IsNullOrWhiteSpace(path))
|
|||
|
{
|
|||
|
absolutePath = IOPath.GetFullPath(path);
|
|||
|
}
|
|||
|
|
|||
|
return OpenVisualStudio(CodeEditor.CurrentEditorInstallation, solution, absolutePath, line);
|
|||
|
}
|
|||
|
|
|||
|
public static void Initialize()
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|