You've already forked com.unity.ide.cursor
mirror of
https://github.com/boxqkrtm/com.unity.ide.cursor.git
synced 2026-05-14 14:20:09 +00:00
com.unity.ide.visualstudio@2.0.7
## [2.0.7] - 2021-02-02 Integration: Remove com.unity.nuget.newtonsoft-json dependency in favor of the built-in JsonUtility for the VS Test Runner. ## [2.0.6] - 2021-01-20 Project generation: - Improved language version detection. Integration: - Added support for the VS Test Runner. - Added initial support for displaying asset usage. - Fixed remaining issues with special characters in file/path.
This commit is contained in:
100
CHANGELOG.md
100
CHANGELOG.md
@@ -1,89 +1,117 @@
|
||||
# Code Editor Package for Visual Studio
|
||||
|
||||
## [2.0.7] - 2021-02-02
|
||||
|
||||
Integration:
|
||||
|
||||
Remove com.unity.nuget.newtonsoft-json dependency in favor of the built-in JsonUtility for the VS Test Runner.
|
||||
|
||||
|
||||
## [2.0.6] - 2021-01-20
|
||||
|
||||
Project generation:
|
||||
|
||||
- Improved language version detection.
|
||||
|
||||
Integration:
|
||||
|
||||
- Added support for the VS Test Runner.
|
||||
- Added initial support for displaying asset usage.
|
||||
- Fixed remaining issues with special characters in file/path.
|
||||
|
||||
## [2.0.5] - 2020-10-30
|
||||
|
||||
Integration:
|
||||
|
||||
Disable legacy pdb symbol checking for Unity packages
|
||||
- Disable legacy pdb symbol checking for Unity packages.
|
||||
|
||||
## [2.0.4] - 2020-10-15
|
||||
|
||||
Project generation:
|
||||
|
||||
- Added support for embedded Roslyn analyzer DLLs and ruleset files.
|
||||
- Warn the user when the opened script is not part of the generation scope.
|
||||
- Warn the user when the selected Visual Studio installation is not found.
|
||||
- Generate a .vsconfig file to ensure Visual Studio installation is compatible.
|
||||
|
||||
Integration:
|
||||
|
||||
- Fix automation issues on MacOS, where a new Visual Studio instance is opened every time.
|
||||
|
||||
## [2.0.3] - 2020-09-09
|
||||
|
||||
Project generation:
|
||||
|
||||
Added C#8 language support.
|
||||
Added UnityProjectGeneratorVersion property.
|
||||
Local and Embedded packages are now selected by default for generation.
|
||||
Added support for asmdef root namespace.
|
||||
- Added C#8 language support.
|
||||
- Added UnityProjectGeneratorVersion property.
|
||||
- Local and Embedded packages are now selected by default for generation.
|
||||
- Added support for asmdef root namespace.
|
||||
|
||||
Integration:
|
||||
|
||||
When the user disabled auto-refresh in Unity, do not try to force refresh the Asset database.
|
||||
Fix Visual Studio detection issues with languages using special characters.
|
||||
- When the user disabled auto-refresh in Unity, do not try to force refresh the Asset database.
|
||||
- Fix Visual Studio detection issues with languages using special characters.
|
||||
|
||||
|
||||
## [2.0.2] - 2020-05-27
|
||||
|
||||
Added support for solution folders.
|
||||
Only bind the messenger when the VS editor is selected.
|
||||
Warn when unable to create the messenger.
|
||||
Fixed an initialization issue triggering legacy code generation.
|
||||
Allow package source in assembly to be generated when referenced from asmref.
|
||||
- Added support for solution folders.
|
||||
- Only bind the messenger when the VS editor is selected.
|
||||
- Warn when unable to create the messenger.
|
||||
- Fixed an initialization issue triggering legacy code generation.
|
||||
- Allow package source in assembly to be generated when referenced from asmref.
|
||||
|
||||
|
||||
## [2.0.1] - 2020-03-19
|
||||
|
||||
When Visual Studio installation is compatible with C# 8.0, setup the language version to not prompt the user with unsupported constructs. (So far Unity only supports C# 7.3).
|
||||
Use Unity's TypeCache to improve project generation speed.
|
||||
Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
|
||||
Add support for selective project generation (embedded, local, registry, git, builtin, player).
|
||||
|
||||
- When Visual Studio installation is compatible with C# 8.0, setup the language version to not prompt the user with unsupported constructs. (So far Unity only supports C# 7.3).
|
||||
- Use Unity's TypeCache to improve project generation speed.
|
||||
- Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
|
||||
- Add support for selective project generation (embedded, local, registry, git, builtin, player).
|
||||
|
||||
## [2.0.0] - 2019-11-06
|
||||
|
||||
- Improved Visual Studio and Visual Studio for Mac automatic discovery
|
||||
- Added support for the VSTU messaging system (start/stop features from Visual Studio)
|
||||
- Added support for solution roundtrip (preserves references to external projects and solution properties)
|
||||
- Added support for VSTU Analyzers (requires Visual Studio 2019 16.3, Visual Studio for Mac 8.3)
|
||||
- Improved Visual Studio and Visual Studio for Mac automatic discovery.
|
||||
- Added support for the VSTU messaging system (start/stop features from Visual Studio).
|
||||
- Added support for solution roundtrip (preserves references to external projects and solution properties).
|
||||
- Added support for VSTU Analyzers (requires Visual Studio 2019 16.3, Visual Studio for Mac 8.3).
|
||||
- Added a warning when using legacy pdb symbol files.
|
||||
- Fixed issues while Opening Visual Studio on Windows
|
||||
- Fixed issues while Opening Visual Studio on Mac
|
||||
- Fixed issues while Opening Visual Studio on Windows.
|
||||
- Fixed issues while Opening Visual Studio on Mac.
|
||||
|
||||
## [1.1.1] - 2019-05-29
|
||||
|
||||
Fix Bridge assembly loading with non VS2017 editors
|
||||
- Fix Bridge assembly loading with non VS2017 editors.
|
||||
|
||||
## [1.1.0] - 2019-05-27
|
||||
|
||||
Move internal extension handling to package.
|
||||
- Move internal extension handling to package.
|
||||
|
||||
## [1.0.11] - 2019-05-21
|
||||
|
||||
Fix detection of visual studio for mac installation.
|
||||
- Fix detection of visual studio for mac installation.
|
||||
|
||||
## [1.0.10] - 2019-05-04
|
||||
|
||||
Fix ignored comintegration executable
|
||||
|
||||
- Fix ignored comintegration executable.
|
||||
|
||||
## [1.0.9] - 2019-03-05
|
||||
|
||||
Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin
|
||||
Use release build of COMIntegration for Visual Studio
|
||||
|
||||
- Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin.
|
||||
- Use release build of COMIntegration for Visual Studio.
|
||||
|
||||
## [1.0.7] - 2019-04-30
|
||||
|
||||
Ensure asset database is refreshed when generating csproj and solution files.
|
||||
- Ensure asset database is refreshed when generating csproj and solution files.
|
||||
|
||||
## [1.0.6] - 2019-04-27
|
||||
|
||||
Add support for generating all csproj files.
|
||||
- Add support for generating all csproj files.
|
||||
|
||||
## [1.0.5] - 2019-04-18
|
||||
|
||||
Fix relative package paths.
|
||||
Fix opening editor on mac.
|
||||
- Fix relative package paths.
|
||||
- Fix opening editor on mac.
|
||||
|
||||
## [1.0.4] - 2019-04-12
|
||||
|
||||
@@ -94,4 +122,4 @@ Fix opening editor on mac.
|
||||
|
||||
### This is the first release of *Unity Package visualstudio_editor*.
|
||||
|
||||
Using the newly created api to integrate Visual Studio with Unity.
|
||||
- Using the newly created api to integrate Visual Studio with Unity.
|
||||
|
||||
Binary file not shown.
@@ -57,7 +57,17 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
return path.Replace(WinSeparator, UnixSeparator);
|
||||
}
|
||||
|
||||
internal static bool IsFileInProjectDirectory(string fileName)
|
||||
internal static bool IsFileInProjectRootDirectory(string fileName)
|
||||
{
|
||||
var relative = MakeRelativeToProjectPath(fileName);
|
||||
if (string.IsNullOrEmpty(relative))
|
||||
return false;
|
||||
|
||||
return relative == Path.GetFileName(relative);
|
||||
}
|
||||
|
||||
// returns null if outside of the project scope
|
||||
internal static string MakeRelativeToProjectPath(string fileName)
|
||||
{
|
||||
var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
|
||||
fileName = Normalize(fileName);
|
||||
@@ -65,7 +75,13 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
if (!Path.IsPathRooted(fileName))
|
||||
fileName = Path.Combine(basePath, fileName);
|
||||
|
||||
return string.Equals(Path.GetDirectoryName(fileName), basePath, StringComparison.OrdinalIgnoreCase);
|
||||
if (!fileName.StartsWith(basePath, StringComparison.OrdinalIgnoreCase))
|
||||
return null;
|
||||
|
||||
return fileName
|
||||
.Substring(basePath.Length)
|
||||
.Trim(Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
{
|
||||
private readonly BinaryReader _reader;
|
||||
|
||||
// Max UDP packet size is 65507
|
||||
private const int MaxStringLength = 65000;
|
||||
|
||||
public Deserializer(byte[] buffer)
|
||||
{
|
||||
_reader = new BinaryReader(new MemoryStream(buffer));
|
||||
@@ -27,7 +24,7 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
public string ReadString()
|
||||
{
|
||||
var length = ReadInt32();
|
||||
return length > 0 && length <= MaxStringLength
|
||||
return length > 0
|
||||
? Encoding.UTF8.GetString(_reader.ReadBytes(length))
|
||||
: "";
|
||||
}
|
||||
|
||||
@@ -30,5 +30,19 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
UpdatePackage,
|
||||
|
||||
ProjectPath,
|
||||
|
||||
// This message is a technical one for big messages, not intended to be used directly
|
||||
Tcp,
|
||||
|
||||
RunStarted,
|
||||
RunFinished,
|
||||
TestStarted,
|
||||
TestFinished,
|
||||
TestListRetrieved,
|
||||
|
||||
RetrieveTestList,
|
||||
ExecuteTests,
|
||||
|
||||
ShowUsage
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,23 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
if (message != null)
|
||||
{
|
||||
message.Origin = (IPEndPoint)endPoint;
|
||||
ReceiveMessage?.Invoke(this, new MessageEventArgs(message));
|
||||
|
||||
int port;
|
||||
int bufferSize;
|
||||
if (IsValidTcpMessage(message, out port, out bufferSize))
|
||||
{
|
||||
// switch to TCP mode to handle big messages
|
||||
TcpClient.Queue(message.Origin.Address, port, bufferSize, buffer =>
|
||||
{
|
||||
var originalMessage = DeserializeMessage(buffer);
|
||||
originalMessage.Origin = message.Origin;
|
||||
ReceiveMessage?.Invoke(this, new MessageEventArgs(originalMessage));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ReceiveMessage?.Invoke(this, new MessageEventArgs(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
@@ -86,6 +102,22 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
BeginReceiveMessage();
|
||||
}
|
||||
|
||||
private static bool IsValidTcpMessage(Message message, out int port, out int bufferSize)
|
||||
{
|
||||
port = 0;
|
||||
bufferSize = 0;
|
||||
if (message.Value == null)
|
||||
return false;
|
||||
if (message.Type != MessageType.Tcp)
|
||||
return false;
|
||||
var parts = message.Value.Split(':');
|
||||
if (parts.Length != 2)
|
||||
return false;
|
||||
if (!int.TryParse(parts[0], out port))
|
||||
return false;
|
||||
return int.TryParse(parts[1], out bufferSize);
|
||||
}
|
||||
|
||||
private void RaiseMessagerException(Exception e)
|
||||
{
|
||||
MessagerException?.Invoke(this, new ExceptionEventArgs(e));
|
||||
@@ -108,6 +140,18 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (buffer.Length >= UdpSocket.BufferSize)
|
||||
{
|
||||
// switch to TCP mode to handle big messages
|
||||
var port = TcpListener.Queue(buffer);
|
||||
if (port > 0)
|
||||
{
|
||||
// success, replace original message with "switch to tcp" marker + port information + buffer length
|
||||
message = MessageFor(MessageType.Tcp, string.Concat(port, ':', buffer.Length));
|
||||
buffer = SerializeMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
_socket.BeginSendTo(buffer, 0, Math.Min(buffer.Length, UdpSocket.BufferSize), SocketFlags.None, target, SendMessageCallback, null);
|
||||
}
|
||||
}
|
||||
|
||||
93
Editor/Messaging/TcpClient.cs
Normal file
93
Editor/Messaging/TcpClient.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
{
|
||||
internal class TcpClient
|
||||
{
|
||||
private const int ConnectOrReadTimeoutMilliseconds = 5000;
|
||||
|
||||
private class State
|
||||
{
|
||||
public System.Net.Sockets.TcpClient TcpClient;
|
||||
public NetworkStream NetworkStream;
|
||||
public byte[] Buffer;
|
||||
public Action<byte[]> OnBufferAvailable;
|
||||
}
|
||||
|
||||
public static void Queue(IPAddress address, int port, int bufferSize, Action<byte[]> onBufferAvailable)
|
||||
{
|
||||
var client = new System.Net.Sockets.TcpClient();
|
||||
var state = new State {OnBufferAvailable = onBufferAvailable, TcpClient = client, Buffer = new byte[bufferSize]};
|
||||
|
||||
try
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
var handle = client.BeginConnect(address, port, OnClientConnected, state);
|
||||
if (!handle.AsyncWaitHandle.WaitOne(ConnectOrReadTimeoutMilliseconds))
|
||||
Cleanup(state);
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Cleanup(state);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnClientConnected(IAsyncResult result)
|
||||
{
|
||||
var state = (State)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
state.TcpClient.EndConnect(result);
|
||||
state.NetworkStream = state.TcpClient.GetStream();
|
||||
var handle = state.NetworkStream.BeginRead(state.Buffer, 0, state.Buffer.Length, OnEndRead, state);
|
||||
if (!handle.AsyncWaitHandle.WaitOne(ConnectOrReadTimeoutMilliseconds))
|
||||
Cleanup(state);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Cleanup(state);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnEndRead(IAsyncResult result)
|
||||
{
|
||||
var state = (State)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
var count = state.NetworkStream.EndRead(result);
|
||||
if (count == state.Buffer.Length)
|
||||
state.OnBufferAvailable?.Invoke(state.Buffer);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore and cleanup
|
||||
}
|
||||
finally
|
||||
{
|
||||
Cleanup(state);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Cleanup(State state)
|
||||
{
|
||||
state.NetworkStream?.Dispose();
|
||||
state.TcpClient?.Close();
|
||||
|
||||
state.NetworkStream = null;
|
||||
state.TcpClient = null;
|
||||
state.Buffer = null;
|
||||
state.OnBufferAvailable = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Messaging/TcpClient.cs.meta
Normal file
11
Editor/Messaging/TcpClient.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6674c38820d12a49ac116d416521d85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
82
Editor/Messaging/TcpListener.cs
Normal file
82
Editor/Messaging/TcpListener.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
{
|
||||
internal class TcpListener
|
||||
{
|
||||
private const int ListenTimeoutMilliseconds = 5000;
|
||||
|
||||
private class State
|
||||
{
|
||||
public System.Net.Sockets.TcpListener TcpListener;
|
||||
public byte[] Buffer;
|
||||
}
|
||||
|
||||
public static int Queue(byte[] buffer)
|
||||
{
|
||||
var tcpListener = new System.Net.Sockets.TcpListener(IPAddress.Any, 0);
|
||||
var state = new State {Buffer = buffer, TcpListener = tcpListener};
|
||||
|
||||
try
|
||||
{
|
||||
tcpListener.Start();
|
||||
|
||||
int port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
|
||||
|
||||
ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
bool listening = true;
|
||||
|
||||
while (listening)
|
||||
{
|
||||
var handle = tcpListener.BeginAcceptTcpClient(OnIncomingConnection, state);
|
||||
listening = handle.AsyncWaitHandle.WaitOne(ListenTimeoutMilliseconds);
|
||||
}
|
||||
|
||||
Cleanup(state);
|
||||
});
|
||||
|
||||
return port;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Cleanup(state);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIncomingConnection(IAsyncResult result)
|
||||
{
|
||||
var state = (State)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
using (var client = state.TcpListener.EndAcceptTcpClient(result))
|
||||
{
|
||||
using (var stream = client.GetStream())
|
||||
{
|
||||
stream.Write(state.Buffer, 0, state.Buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore and cleanup
|
||||
}
|
||||
}
|
||||
|
||||
private static void Cleanup(State state)
|
||||
{
|
||||
state.TcpListener?.Stop();
|
||||
|
||||
state.TcpListener = null;
|
||||
state.Buffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Messaging/TcpListener.cs.meta
Normal file
11
Editor/Messaging/TcpListener.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ded625cf0d03fa94c9f939fd13ced18d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,6 +10,8 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
||||
{
|
||||
internal class UdpSocket : Socket
|
||||
{
|
||||
// Maximum UDP payload is 65507 bytes.
|
||||
// TCP mode will be used when the payload is bigger than this BufferSize
|
||||
public const int BufferSize = 1024 * 8;
|
||||
|
||||
internal UdpSocket()
|
||||
|
||||
@@ -560,15 +560,13 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
var targetFrameworkVersion = "v4.7.1";
|
||||
var targetLanguageVersion = "latest"; // danger: latest is not the same absolute value depending on the VS version.
|
||||
|
||||
if (m_CurrentInstallation != null && m_CurrentInstallation.SupportsCSharp8)
|
||||
if (m_CurrentInstallation != null)
|
||||
{
|
||||
// Current VS installation is compatible with C# 8.
|
||||
var vsLanguageSupport = m_CurrentInstallation.LatestLanguageVersionSupported;
|
||||
var unityLanguageSupport = UnityInstallation.LatestLanguageVersionSupported(assembly);
|
||||
|
||||
#if !UNITY_2020_2_OR_NEWER
|
||||
// Unity 2020.2.0a12 added support for C# 8
|
||||
// <=2020.1 has no support for C# 8 constructs, so tell the compiler to accept only C# 7.3 or lower.
|
||||
targetLanguageVersion = "7.3";
|
||||
#endif
|
||||
// Use the minimal supported version between VS and Unity, so that compilation will work in both
|
||||
targetLanguageVersion = (vsLanguageSupport <= unityLanguageSupport ? vsLanguageSupport : unityLanguageSupport).ToString(2); // (major, minor) only
|
||||
}
|
||||
|
||||
var projectType = ProjectTypeOf(assembly.name);
|
||||
@@ -801,7 +799,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
// Add all projects that were previously in the solution and that are not generated by Unity, nor generated in the project root directory
|
||||
var externalProjects = previousSolution.Projects
|
||||
.Where(p => p.IsSolutionFolderProjectFactory() || !FileUtility.IsFileInProjectDirectory(p.FileName))
|
||||
.Where(p => p.IsSolutionFolderProjectFactory() || !FileUtility.IsFileInProjectRootDirectory(p.FileName))
|
||||
.Where(p => generatedProjects.All(gp => gp.FileName != p.FileName));
|
||||
|
||||
projects.AddRange(externalProjects);
|
||||
|
||||
8
Editor/Testing.meta
Normal file
8
Editor/Testing.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f9f1d015d7a8ba46b7d71acfcda3ae7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
39
Editor/Testing/TestAdaptor.cs
Normal file
39
Editor/Testing/TestAdaptor.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Testing
|
||||
{
|
||||
[Serializable]
|
||||
internal class TestAdaptorContainer
|
||||
{
|
||||
public TestAdaptor[] TestAdaptors;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class TestAdaptor
|
||||
{
|
||||
public string Id;
|
||||
public string Name;
|
||||
public string FullName;
|
||||
|
||||
public string Type;
|
||||
public string Method;
|
||||
public string Assembly;
|
||||
|
||||
public int Parent;
|
||||
|
||||
public TestAdaptor(ITestAdaptor testAdaptor, int parent)
|
||||
{
|
||||
Id = testAdaptor.Id;
|
||||
Name = testAdaptor.Name;
|
||||
FullName = testAdaptor.FullName;
|
||||
|
||||
Type = testAdaptor.TypeInfo?.FullName;
|
||||
Method = testAdaptor?.Method?.Name;
|
||||
Assembly = testAdaptor.TypeInfo?.Assembly?.Location;
|
||||
|
||||
Parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Testing/TestAdaptor.cs.meta
Normal file
11
Editor/Testing/TestAdaptor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b73b3de0d473d4a1c887ab31f69b1a8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
60
Editor/Testing/TestResultAdaptor.cs
Normal file
60
Editor/Testing/TestResultAdaptor.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Testing
|
||||
{
|
||||
[Serializable]
|
||||
internal class TestResultAdaptorContainer
|
||||
{
|
||||
public TestResultAdaptor[] TestResultAdaptors;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class TestResultAdaptor
|
||||
{
|
||||
public string Name;
|
||||
public string FullName;
|
||||
|
||||
public int PassCount;
|
||||
public int FailCount;
|
||||
public int InconclusiveCount;
|
||||
public int SkipCount;
|
||||
|
||||
public string ResultState;
|
||||
public string StackTrace;
|
||||
|
||||
public TestStatusAdaptor TestStatus;
|
||||
|
||||
public int Parent;
|
||||
|
||||
public TestResultAdaptor(ITestResultAdaptor testResultAdaptor, int parent)
|
||||
{
|
||||
Name = testResultAdaptor.Name;
|
||||
FullName = testResultAdaptor.FullName;
|
||||
|
||||
PassCount = testResultAdaptor.PassCount;
|
||||
FailCount = testResultAdaptor.FailCount;
|
||||
InconclusiveCount = testResultAdaptor.InconclusiveCount;
|
||||
SkipCount = testResultAdaptor.SkipCount;
|
||||
|
||||
switch (testResultAdaptor.TestStatus)
|
||||
{
|
||||
case UnityEditor.TestTools.TestRunner.Api.TestStatus.Passed:
|
||||
TestStatus = TestStatusAdaptor.Passed;
|
||||
break;
|
||||
case UnityEditor.TestTools.TestRunner.Api.TestStatus.Skipped:
|
||||
TestStatus = TestStatusAdaptor.Skipped;
|
||||
break;
|
||||
case UnityEditor.TestTools.TestRunner.Api.TestStatus.Inconclusive:
|
||||
TestStatus = TestStatusAdaptor.Inconclusive;
|
||||
break;
|
||||
case UnityEditor.TestTools.TestRunner.Api.TestStatus.Failed:
|
||||
TestStatus = TestStatusAdaptor.Failed;
|
||||
break;
|
||||
}
|
||||
|
||||
Parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Testing/TestResultAdaptor.cs.meta
Normal file
11
Editor/Testing/TestResultAdaptor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f47f2d030bc1d415a8d15a51dbcc39a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
Editor/Testing/TestRunnerApiListener.cs
Normal file
52
Editor/Testing/TestRunnerApiListener.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Testing
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
internal class TestRunnerApiListener
|
||||
{
|
||||
private static TestRunnerApi _testRunnerApi;
|
||||
private static TestRunnerCallbacks _testRunnerCallbacks;
|
||||
|
||||
static TestRunnerApiListener()
|
||||
{
|
||||
_testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
|
||||
_testRunnerCallbacks = new TestRunnerCallbacks();
|
||||
|
||||
_testRunnerApi.RegisterCallbacks(_testRunnerCallbacks);
|
||||
}
|
||||
|
||||
public static void RetrieveTestList(string mode)
|
||||
{
|
||||
RetrieveTestList((TestMode) Enum.Parse(typeof(TestMode), mode));
|
||||
}
|
||||
|
||||
private static void RetrieveTestList(TestMode mode)
|
||||
{
|
||||
_testRunnerApi.RetrieveTestList(mode, (ta) => _testRunnerCallbacks.TestListRetrieved(mode, ta));
|
||||
}
|
||||
|
||||
public static void ExecuteTests(string command)
|
||||
{
|
||||
// ExecuteTests format:
|
||||
// TestMode:FullName
|
||||
|
||||
var index = command.IndexOf(':');
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
var testMode = (TestMode)Enum.Parse(typeof(TestMode), command.Substring(0, index));
|
||||
var filter = command.Substring(index + 1);
|
||||
|
||||
ExecuteTests(new Filter() { testMode = testMode, testNames = new string[] { filter } });
|
||||
}
|
||||
|
||||
private static void ExecuteTests(Filter filter)
|
||||
{
|
||||
_testRunnerApi.Execute(new ExecutionSettings(filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Testing/TestRunnerApiListener.cs.meta
Normal file
11
Editor/Testing/TestRunnerApiListener.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b59b40c84c6a5348a188c16b17c7b40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
90
Editor/Testing/TestRunnerCallbacks.cs
Normal file
90
Editor/Testing/TestRunnerCallbacks.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Testing
|
||||
{
|
||||
internal class TestRunnerCallbacks : ICallbacks
|
||||
{
|
||||
private string Serialize<TContainer, TSource, TAdaptor>(
|
||||
TSource source,
|
||||
Func<TSource, int, TAdaptor> createAdaptor,
|
||||
Func<TSource, IEnumerable<TSource>> children,
|
||||
Func<TAdaptor[], TContainer> container)
|
||||
{
|
||||
var adaptors = new List<TAdaptor>();
|
||||
|
||||
void AddAdaptor(TSource item, int parentIndex)
|
||||
{
|
||||
var index = adaptors.Count;
|
||||
adaptors.Add(createAdaptor(item, parentIndex));
|
||||
foreach (var child in children(item))
|
||||
AddAdaptor(child, index);
|
||||
}
|
||||
|
||||
AddAdaptor(source, -1);
|
||||
|
||||
return JsonUtility.ToJson(container(adaptors.ToArray()));
|
||||
}
|
||||
|
||||
private string Serialize(ITestAdaptor testAdaptor)
|
||||
{
|
||||
return Serialize(
|
||||
testAdaptor,
|
||||
(a, parentIndex) => new TestAdaptor(a, parentIndex),
|
||||
(a) => a.Children,
|
||||
(r) => new TestAdaptorContainer { TestAdaptors = r });
|
||||
}
|
||||
|
||||
private string Serialize(ITestResultAdaptor testResultAdaptor)
|
||||
{
|
||||
return Serialize(
|
||||
testResultAdaptor,
|
||||
(a, parentIndex) => new TestResultAdaptor(a, parentIndex),
|
||||
(a) => a.Children,
|
||||
(r) => new TestResultAdaptorContainer { TestResultAdaptors = r });
|
||||
}
|
||||
|
||||
public void RunFinished(ITestResultAdaptor testResultAdaptor)
|
||||
{
|
||||
VisualStudioIntegration.BroadcastMessage(Messaging.MessageType.RunFinished, Serialize(testResultAdaptor));
|
||||
}
|
||||
|
||||
public void RunStarted(ITestAdaptor testAdaptor)
|
||||
{
|
||||
VisualStudioIntegration.BroadcastMessage(Messaging.MessageType.RunStarted, Serialize(testAdaptor));
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResultAdaptor testResultAdaptor)
|
||||
{
|
||||
VisualStudioIntegration.BroadcastMessage(Messaging.MessageType.TestFinished, Serialize(testResultAdaptor));
|
||||
}
|
||||
|
||||
public void TestStarted(ITestAdaptor testAdaptor)
|
||||
{
|
||||
VisualStudioIntegration.BroadcastMessage(Messaging.MessageType.TestStarted, Serialize(testAdaptor));
|
||||
}
|
||||
|
||||
private static string TestModeName(TestMode testMode)
|
||||
{
|
||||
switch (testMode)
|
||||
{
|
||||
case TestMode.EditMode: return "EditMode";
|
||||
case TestMode.PlayMode: return "PlayMode";
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
|
||||
internal void TestListRetrieved(TestMode testMode, ITestAdaptor testAdaptor)
|
||||
{
|
||||
// TestListRetrieved format:
|
||||
// TestMode:Json
|
||||
|
||||
var value = TestModeName(testMode) + ":" + Serialize(testAdaptor);
|
||||
VisualStudioIntegration.BroadcastMessage(Messaging.MessageType.TestListRetrieved, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/Testing/TestRunnerCallbacks.cs.meta
Normal file
11
Editor/Testing/TestRunnerCallbacks.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fae6007c1ac2cc744b2891fd4d279c96
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Editor/Testing/TestStatusAdaptor.cs
Normal file
13
Editor/Testing/TestStatusAdaptor.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor.Testing
|
||||
{
|
||||
[Serializable]
|
||||
internal enum TestStatusAdaptor
|
||||
{
|
||||
Passed,
|
||||
Skipped,
|
||||
Inconclusive,
|
||||
Failed,
|
||||
}
|
||||
}
|
||||
11
Editor/Testing/TestStatusAdaptor.cs.meta
Normal file
11
Editor/Testing/TestStatusAdaptor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0719f1a8b2a284e1182b352e6c8c3c60
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Editor/UnityInstallation.cs
Normal file
27
Editor/UnityInstallation.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using UnityEditor.Compilation;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
internal static class UnityInstallation
|
||||
{
|
||||
public static Version LatestLanguageVersionSupported(Assembly assembly)
|
||||
{
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
if (assembly?.compilerOptions != null && Version.TryParse(assembly.compilerOptions.LanguageVersion, out var result))
|
||||
return result;
|
||||
|
||||
// if parsing fails, we know at least we have support for 8.0
|
||||
return new Version(8, 0);
|
||||
#else
|
||||
return new Version(7, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Editor/UnityInstallation.cs.meta
Normal file
11
Editor/UnityInstallation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8c76505bcc613640ade706bdb0f1cba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
118
Editor/UsageUtility.cs
Normal file
118
Editor/UsageUtility.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
[Serializable]
|
||||
internal class FileUsage
|
||||
{
|
||||
public string Path;
|
||||
public string[] GameObjectPath;
|
||||
}
|
||||
|
||||
internal static class UsageUtility
|
||||
{
|
||||
internal static void ShowUsage(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
var usage = JsonUtility.FromJson<FileUsage>(json);
|
||||
ShowUsage(usage.Path, usage.GameObjectPath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore malformed request
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ShowUsage(string path, string[] gameObjectPath)
|
||||
{
|
||||
path = FileUtility.MakeRelativeToProjectPath(path);
|
||||
if (path == null)
|
||||
return;
|
||||
|
||||
path = FileUtility.NormalizeWindowsToUnix(path);
|
||||
var extension = Path.GetExtension(path).ToLower();
|
||||
|
||||
EditorUtility.FocusProjectWindow();
|
||||
|
||||
switch (extension)
|
||||
{
|
||||
case ".unity":
|
||||
ShowSceneUsage(path, gameObjectPath);
|
||||
break;
|
||||
default:
|
||||
var asset = AssetDatabase.LoadMainAssetAtPath(path);
|
||||
Selection.activeObject = asset;
|
||||
EditorGUIUtility.PingObject(asset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowSceneUsage(string scenePath, string[] gameObjectPath)
|
||||
{
|
||||
var scene = SceneManager.GetSceneByPath(scenePath.Replace(Path.DirectorySeparatorChar, '/'));
|
||||
if (!scene.isLoaded)
|
||||
{
|
||||
var result = UnityEditor.EditorUtility.DisplayDialogComplex("Show Usage",
|
||||
$"Do you want to open \"{Path.GetFileName(scenePath)}\"?",
|
||||
"Open Scene",
|
||||
"Cancel",
|
||||
"Open Scene (additive)");
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
|
||||
scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
|
||||
break;
|
||||
case 1:
|
||||
return;
|
||||
case 2:
|
||||
scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShowSceneUsage(scene, gameObjectPath);
|
||||
}
|
||||
|
||||
private static void ShowSceneUsage(Scene scene, string[] gameObjectPath)
|
||||
{
|
||||
if (gameObjectPath == null || gameObjectPath.Length == 0)
|
||||
return;
|
||||
|
||||
var go = scene.GetRootGameObjects().FirstOrDefault(g => g.name == gameObjectPath[0]);
|
||||
if (go == null)
|
||||
return;
|
||||
|
||||
for (var ni = 1; ni < gameObjectPath.Length; ni++)
|
||||
{
|
||||
var transform = go.transform;
|
||||
for (var i = 0; i < transform.childCount; i++)
|
||||
{
|
||||
var child = transform.GetChild(i);
|
||||
var childgo = child.gameObject;
|
||||
if (childgo.name == gameObjectPath[ni])
|
||||
{
|
||||
go = childgo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Selection.activeObject = go;
|
||||
EditorGUIUtility.PingObject(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/UsageUtility.cs.meta
Normal file
11
Editor/UsageUtility.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a7aba2d3d458e04eb4210c0303fbf64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Editor/VersionPair.cs
Normal file
16
Editor/VersionPair.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
internal struct VersionPair
|
||||
{
|
||||
public Version IdeVersion;
|
||||
public Version LanguageVersion;
|
||||
|
||||
public VersionPair(int idemajor, int ideminor, int languageMajor, int languageMinor)
|
||||
{
|
||||
IdeVersion = new Version(idemajor, ideminor);
|
||||
LanguageVersion = new Version(languageMajor, languageMinor);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/VersionPair.cs.meta
Normal file
11
Editor/VersionPair.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffe1bdf971d321f4db593c4c6ebd6e47
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -11,6 +11,11 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Unity.CodeEditor;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.VisualStudio.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualStudio.Standalone.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
using Unity.CodeEditor;
|
||||
using IOPath = System.IO.Path;
|
||||
@@ -14,7 +15,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
string Path { get; }
|
||||
bool SupportsAnalyzers { get; }
|
||||
bool SupportsCSharp8 { get; }
|
||||
Version LatestLanguageVersionSupported { get; }
|
||||
string[] GetAnalyzers();
|
||||
CodeEditor.Installation ToCodeEditorInstallation();
|
||||
}
|
||||
@@ -40,17 +41,52 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsCSharp8
|
||||
// C# language version support for Visual Studio
|
||||
private static VersionPair[] WindowsVersionTable =
|
||||
{
|
||||
// VisualStudio 2019
|
||||
new VersionPair(16,8, /* => */ 9,0),
|
||||
new VersionPair(16,0, /* => */ 8,0),
|
||||
|
||||
// VisualStudio 2017
|
||||
new VersionPair(15,7, /* => */ 7,3),
|
||||
new VersionPair(15,5, /* => */ 7,2),
|
||||
new VersionPair(15,3, /* => */ 7,1),
|
||||
new VersionPair(15,0, /* => */ 7,0),
|
||||
};
|
||||
|
||||
// C# language version support for Visual Studio for Mac
|
||||
private static VersionPair[] OSXVersionTable =
|
||||
{
|
||||
// VisualStudio for Mac 8.x
|
||||
new VersionPair(8,8, /* => */ 9,0),
|
||||
new VersionPair(8,3, /* => */ 8,0),
|
||||
new VersionPair(8,0, /* => */ 7,3),
|
||||
};
|
||||
|
||||
public Version LatestLanguageVersionSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
VersionPair[] versions = null;
|
||||
|
||||
if (VisualStudioEditor.IsWindows)
|
||||
return Version >= new Version(16, 0);
|
||||
versions = WindowsVersionTable;
|
||||
|
||||
if (VisualStudioEditor.IsOSX)
|
||||
return Version >= new Version(8, 2);
|
||||
versions = OSXVersionTable;
|
||||
|
||||
return false;
|
||||
if (versions != null)
|
||||
{
|
||||
foreach(var entry in versions)
|
||||
{
|
||||
if (Version >= entry.IdeVersion)
|
||||
return entry.LanguageVersion;
|
||||
}
|
||||
}
|
||||
|
||||
// default to 7.0 given we support at least VS 2017
|
||||
return new Version(7,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.Unity.VisualStudio.Editor.Messaging;
|
||||
using Microsoft.Unity.VisualStudio.Editor.Testing;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using MessageType = Microsoft.Unity.VisualStudio.Editor.Messaging.MessageType;
|
||||
@@ -17,10 +19,18 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
[InitializeOnLoad]
|
||||
internal class VisualStudioIntegration
|
||||
{
|
||||
class Client
|
||||
{
|
||||
public IPEndPoint EndPoint { get; set; }
|
||||
public DateTime LastMessage { get; set; }
|
||||
}
|
||||
|
||||
private static Messager _messager;
|
||||
|
||||
private static readonly Queue<Message> Incoming = new Queue<Message>();
|
||||
private static readonly object IncomingLock = new object();
|
||||
private static readonly Queue<Message> _incoming = new Queue<Message>();
|
||||
private static readonly Dictionary<IPEndPoint, Client> _clients = new Dictionary<IPEndPoint, Client>();
|
||||
private static readonly object _incomingLock = new object();
|
||||
private static readonly object _clientsLock = new object();
|
||||
|
||||
static VisualStudioIntegration()
|
||||
{
|
||||
@@ -90,25 +100,39 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
|
||||
private static void OnUpdate()
|
||||
{
|
||||
lock (IncomingLock)
|
||||
lock (_incomingLock)
|
||||
{
|
||||
while (Incoming.Count > 0)
|
||||
while (_incoming.Count > 0)
|
||||
{
|
||||
ProcessIncoming(Incoming.Dequeue());
|
||||
ProcessIncoming(_incoming.Dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
lock (_clientsLock)
|
||||
{
|
||||
foreach (var client in _clients.Values.ToArray())
|
||||
{
|
||||
if (DateTime.Now.Subtract(client.LastMessage) > TimeSpan.FromMilliseconds(4000))
|
||||
_clients.Remove(client.EndPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddMessage(Message message)
|
||||
{
|
||||
lock (IncomingLock)
|
||||
lock (_incomingLock)
|
||||
{
|
||||
Incoming.Enqueue(message);
|
||||
_incoming.Enqueue(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessIncoming(Message message)
|
||||
{
|
||||
lock (_clientsLock)
|
||||
{
|
||||
CheckClient(message);
|
||||
}
|
||||
|
||||
switch (message.Type)
|
||||
{
|
||||
case MessageType.Ping:
|
||||
@@ -142,6 +166,36 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
case MessageType.ProjectPath:
|
||||
Answer(message, MessageType.ProjectPath, Path.GetFullPath(Path.Combine(Application.dataPath, "..")));
|
||||
break;
|
||||
case MessageType.ExecuteTests:
|
||||
TestRunnerApiListener.ExecuteTests(message.Value);
|
||||
break;
|
||||
case MessageType.RetrieveTestList:
|
||||
TestRunnerApiListener.RetrieveTestList(message.Value);
|
||||
break;
|
||||
case MessageType.ShowUsage:
|
||||
UsageUtility.ShowUsage(message.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckClient(Message message)
|
||||
{
|
||||
Client client;
|
||||
var endPoint = message.Origin;
|
||||
|
||||
if (!_clients.TryGetValue(endPoint, out client))
|
||||
{
|
||||
client = new Client
|
||||
{
|
||||
EndPoint = endPoint,
|
||||
LastMessage = DateTime.Now
|
||||
};
|
||||
|
||||
_clients.Add(endPoint, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.LastMessage = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +219,11 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
AddMessage(message);
|
||||
}
|
||||
|
||||
private static void Answer(Client client, MessageType answerType, string answerValue)
|
||||
{
|
||||
Answer(client.EndPoint, answerType, answerValue);
|
||||
}
|
||||
|
||||
private static void Answer(Message message, MessageType answerType, string answerValue = "")
|
||||
{
|
||||
var targetEndPoint = message.Origin;
|
||||
@@ -189,5 +248,16 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
_messager.Dispose();
|
||||
_messager = null;
|
||||
}
|
||||
|
||||
internal static void BroadcastMessage(MessageType type, string value)
|
||||
{
|
||||
lock (_clientsLock)
|
||||
{
|
||||
foreach (var client in _clients.Values.ToArray())
|
||||
{
|
||||
Answer(client, type, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
{
|
||||
"name": "Unity.VisualStudio.Editor",
|
||||
"references": [],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"Newtonsoft.Json.dll"
|
||||
],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
11
package.json
11
package.json
@@ -2,18 +2,21 @@
|
||||
"name": "com.unity.ide.visualstudio",
|
||||
"displayName": "Visual Studio Editor",
|
||||
"description": "Code editor integration for supporting Visual Studio as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.",
|
||||
"version": "2.0.5",
|
||||
"version": "2.0.7",
|
||||
"unity": "2020.1",
|
||||
"unityRelease": "0a12",
|
||||
"dependencies": {
|
||||
"com.unity.test-framework": "1.1.9"
|
||||
},
|
||||
"relatedPackages": {
|
||||
"com.unity.ide.visualstudio.tests": "2.0.5"
|
||||
"com.unity.ide.visualstudio.tests": "2.0.7"
|
||||
},
|
||||
"upmCi": {
|
||||
"footprint": "848c02b3f0fe476a599004cd972346a89e39d26f"
|
||||
"footprint": "b6515ac9d75224fe45e288270d26a9e031c550a8"
|
||||
},
|
||||
"repository": {
|
||||
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git",
|
||||
"type": "git",
|
||||
"revision": "83ca94e82bb6da515dc57e0d860b6b2224f56991"
|
||||
"revision": "dec282022c7a95fada560c36f53da9dd155a142c"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user