You've already forked com.unity.ide.cursor
mirror of
https://github.com/boxqkrtm/com.unity.ide.cursor.git
synced 2026-05-14 22:30:10 +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
|
# 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
|
## [2.0.5] - 2020-10-30
|
||||||
|
|
||||||
Integration:
|
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
|
## [2.0.3] - 2020-09-09
|
||||||
|
|
||||||
Project generation:
|
Project generation:
|
||||||
|
|
||||||
Added C#8 language support.
|
- Added C#8 language support.
|
||||||
Added UnityProjectGeneratorVersion property.
|
- Added UnityProjectGeneratorVersion property.
|
||||||
Local and Embedded packages are now selected by default for generation.
|
- Local and Embedded packages are now selected by default for generation.
|
||||||
Added support for asmdef root namespace.
|
- Added support for asmdef root namespace.
|
||||||
|
|
||||||
Integration:
|
Integration:
|
||||||
|
|
||||||
When the user disabled auto-refresh in Unity, do not try to force refresh the Asset database.
|
- 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.
|
- Fix Visual Studio detection issues with languages using special characters.
|
||||||
|
|
||||||
|
|
||||||
## [2.0.2] - 2020-05-27
|
## [2.0.2] - 2020-05-27
|
||||||
|
|
||||||
Added support for solution folders.
|
- Added support for solution folders.
|
||||||
Only bind the messenger when the VS editor is selected.
|
- Only bind the messenger when the VS editor is selected.
|
||||||
Warn when unable to create the messenger.
|
- Warn when unable to create the messenger.
|
||||||
Fixed an initialization issue triggering legacy code generation.
|
- Fixed an initialization issue triggering legacy code generation.
|
||||||
Allow package source in assembly to be generated when referenced from asmref.
|
- Allow package source in assembly to be generated when referenced from asmref.
|
||||||
|
|
||||||
|
|
||||||
## [2.0.1] - 2020-03-19
|
## [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).
|
- 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.
|
- Use Unity's TypeCache to improve project generation speed.
|
||||||
Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
|
- 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).
|
- Add support for selective project generation (embedded, local, registry, git, builtin, player).
|
||||||
|
|
||||||
|
|
||||||
## [2.0.0] - 2019-11-06
|
## [2.0.0] - 2019-11-06
|
||||||
|
|
||||||
- Improved Visual Studio and Visual Studio for Mac automatic discovery
|
- 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 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 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 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.
|
- Added a warning when using legacy pdb symbol files.
|
||||||
- Fixed issues while Opening Visual Studio on Windows
|
- Fixed issues while Opening Visual Studio on Windows.
|
||||||
- Fixed issues while Opening Visual Studio on Mac
|
- Fixed issues while Opening Visual Studio on Mac.
|
||||||
|
|
||||||
## [1.1.1] - 2019-05-29
|
## [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
|
## [1.1.0] - 2019-05-27
|
||||||
|
|
||||||
Move internal extension handling to package.
|
- Move internal extension handling to package.
|
||||||
|
|
||||||
## [1.0.11] - 2019-05-21
|
## [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
|
## [1.0.10] - 2019-05-04
|
||||||
|
|
||||||
Fix ignored comintegration executable
|
- Fix ignored comintegration executable.
|
||||||
|
|
||||||
|
|
||||||
## [1.0.9] - 2019-03-05
|
## [1.0.9] - 2019-03-05
|
||||||
|
|
||||||
Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin
|
- Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin.
|
||||||
Use release build of COMIntegration for Visual Studio
|
- Use release build of COMIntegration for Visual Studio.
|
||||||
|
|
||||||
|
|
||||||
## [1.0.7] - 2019-04-30
|
## [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
|
## [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
|
## [1.0.5] - 2019-04-18
|
||||||
|
|
||||||
Fix relative package paths.
|
- Fix relative package paths.
|
||||||
Fix opening editor on mac.
|
- Fix opening editor on mac.
|
||||||
|
|
||||||
## [1.0.4] - 2019-04-12
|
## [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*.
|
### 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);
|
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, ".."));
|
var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
|
||||||
fileName = Normalize(fileName);
|
fileName = Normalize(fileName);
|
||||||
@@ -65,7 +75,13 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
if (!Path.IsPathRooted(fileName))
|
if (!Path.IsPathRooted(fileName))
|
||||||
fileName = Path.Combine(basePath, 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;
|
private readonly BinaryReader _reader;
|
||||||
|
|
||||||
// Max UDP packet size is 65507
|
|
||||||
private const int MaxStringLength = 65000;
|
|
||||||
|
|
||||||
public Deserializer(byte[] buffer)
|
public Deserializer(byte[] buffer)
|
||||||
{
|
{
|
||||||
_reader = new BinaryReader(new MemoryStream(buffer));
|
_reader = new BinaryReader(new MemoryStream(buffer));
|
||||||
@@ -27,7 +24,7 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
|||||||
public string ReadString()
|
public string ReadString()
|
||||||
{
|
{
|
||||||
var length = ReadInt32();
|
var length = ReadInt32();
|
||||||
return length > 0 && length <= MaxStringLength
|
return length > 0
|
||||||
? Encoding.UTF8.GetString(_reader.ReadBytes(length))
|
? Encoding.UTF8.GetString(_reader.ReadBytes(length))
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,19 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
|||||||
UpdatePackage,
|
UpdatePackage,
|
||||||
|
|
||||||
ProjectPath,
|
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)
|
if (message != null)
|
||||||
{
|
{
|
||||||
message.Origin = (IPEndPoint)endPoint;
|
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)
|
catch (ObjectDisposedException)
|
||||||
@@ -86,6 +102,22 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
|||||||
BeginReceiveMessage();
|
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)
|
private void RaiseMessagerException(Exception e)
|
||||||
{
|
{
|
||||||
MessagerException?.Invoke(this, new ExceptionEventArgs(e));
|
MessagerException?.Invoke(this, new ExceptionEventArgs(e));
|
||||||
@@ -108,6 +140,18 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
return;
|
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);
|
_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
|
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;
|
public const int BufferSize = 1024 * 8;
|
||||||
|
|
||||||
internal UdpSocket()
|
internal UdpSocket()
|
||||||
|
|||||||
@@ -560,15 +560,13 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
var targetFrameworkVersion = "v4.7.1";
|
var targetFrameworkVersion = "v4.7.1";
|
||||||
var targetLanguageVersion = "latest"; // danger: latest is not the same absolute value depending on the VS version.
|
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
|
// Use the minimal supported version between VS and Unity, so that compilation will work in both
|
||||||
// Unity 2020.2.0a12 added support for C# 8
|
targetLanguageVersion = (vsLanguageSupport <= unityLanguageSupport ? vsLanguageSupport : unityLanguageSupport).ToString(2); // (major, minor) only
|
||||||
// <=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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectType = ProjectTypeOf(assembly.name);
|
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
|
// 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
|
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));
|
.Where(p => generatedProjects.All(gp => gp.FileName != p.FileName));
|
||||||
|
|
||||||
projects.AddRange(externalProjects);
|
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 UnityEngine;
|
||||||
using Unity.CodeEditor;
|
using Unity.CodeEditor;
|
||||||
using System.Runtime.InteropServices;
|
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
|
namespace Microsoft.Unity.VisualStudio.Editor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Unity.CodeEditor;
|
using Unity.CodeEditor;
|
||||||
using IOPath = System.IO.Path;
|
using IOPath = System.IO.Path;
|
||||||
@@ -14,7 +15,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
{
|
{
|
||||||
string Path { get; }
|
string Path { get; }
|
||||||
bool SupportsAnalyzers { get; }
|
bool SupportsAnalyzers { get; }
|
||||||
bool SupportsCSharp8 { get; }
|
Version LatestLanguageVersionSupported { get; }
|
||||||
string[] GetAnalyzers();
|
string[] GetAnalyzers();
|
||||||
CodeEditor.Installation ToCodeEditorInstallation();
|
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
|
get
|
||||||
{
|
{
|
||||||
|
VersionPair[] versions = null;
|
||||||
|
|
||||||
if (VisualStudioEditor.IsWindows)
|
if (VisualStudioEditor.IsWindows)
|
||||||
return Version >= new Version(16, 0);
|
versions = WindowsVersionTable;
|
||||||
|
|
||||||
if (VisualStudioEditor.IsOSX)
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using Microsoft.Unity.VisualStudio.Editor.Messaging;
|
using Microsoft.Unity.VisualStudio.Editor.Messaging;
|
||||||
|
using Microsoft.Unity.VisualStudio.Editor.Testing;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using MessageType = Microsoft.Unity.VisualStudio.Editor.Messaging.MessageType;
|
using MessageType = Microsoft.Unity.VisualStudio.Editor.Messaging.MessageType;
|
||||||
@@ -17,10 +19,18 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
[InitializeOnLoad]
|
[InitializeOnLoad]
|
||||||
internal class VisualStudioIntegration
|
internal class VisualStudioIntegration
|
||||||
{
|
{
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
public IPEndPoint EndPoint { get; set; }
|
||||||
|
public DateTime LastMessage { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private static Messager _messager;
|
private static Messager _messager;
|
||||||
|
|
||||||
private static readonly Queue<Message> Incoming = new Queue<Message>();
|
private static readonly Queue<Message> _incoming = new Queue<Message>();
|
||||||
private static readonly object IncomingLock = new object();
|
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()
|
static VisualStudioIntegration()
|
||||||
{
|
{
|
||||||
@@ -90,25 +100,39 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
|
|
||||||
private static void OnUpdate()
|
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)
|
private static void AddMessage(Message message)
|
||||||
{
|
{
|
||||||
lock (IncomingLock)
|
lock (_incomingLock)
|
||||||
{
|
{
|
||||||
Incoming.Enqueue(message);
|
_incoming.Enqueue(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessIncoming(Message message)
|
private static void ProcessIncoming(Message message)
|
||||||
{
|
{
|
||||||
|
lock (_clientsLock)
|
||||||
|
{
|
||||||
|
CheckClient(message);
|
||||||
|
}
|
||||||
|
|
||||||
switch (message.Type)
|
switch (message.Type)
|
||||||
{
|
{
|
||||||
case MessageType.Ping:
|
case MessageType.Ping:
|
||||||
@@ -142,6 +166,36 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
case MessageType.ProjectPath:
|
case MessageType.ProjectPath:
|
||||||
Answer(message, MessageType.ProjectPath, Path.GetFullPath(Path.Combine(Application.dataPath, "..")));
|
Answer(message, MessageType.ProjectPath, Path.GetFullPath(Path.Combine(Application.dataPath, "..")));
|
||||||
break;
|
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);
|
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 = "")
|
private static void Answer(Message message, MessageType answerType, string answerValue = "")
|
||||||
{
|
{
|
||||||
var targetEndPoint = message.Origin;
|
var targetEndPoint = message.Origin;
|
||||||
@@ -189,5 +248,16 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
_messager.Dispose();
|
_messager.Dispose();
|
||||||
_messager = null;
|
_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",
|
"name": "Unity.VisualStudio.Editor",
|
||||||
"references": [],
|
"references": [],
|
||||||
"optionalUnityReferences": [],
|
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
"Editor"
|
"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",
|
"name": "com.unity.ide.visualstudio",
|
||||||
"displayName": "Visual Studio Editor",
|
"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.",
|
"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",
|
"unity": "2020.1",
|
||||||
"unityRelease": "0a12",
|
"unityRelease": "0a12",
|
||||||
|
"dependencies": {
|
||||||
|
"com.unity.test-framework": "1.1.9"
|
||||||
|
},
|
||||||
"relatedPackages": {
|
"relatedPackages": {
|
||||||
"com.unity.ide.visualstudio.tests": "2.0.5"
|
"com.unity.ide.visualstudio.tests": "2.0.7"
|
||||||
},
|
},
|
||||||
"upmCi": {
|
"upmCi": {
|
||||||
"footprint": "848c02b3f0fe476a599004cd972346a89e39d26f"
|
"footprint": "b6515ac9d75224fe45e288270d26a9e031c550a8"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git",
|
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"revision": "83ca94e82bb6da515dc57e0d860b6b2224f56991"
|
"revision": "dec282022c7a95fada560c36f53da9dd155a142c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user