diff --git a/Build/15.0/packages.config b/Build/15.0/packages.config index 4307af3890..bf42670b37 100644 --- a/Build/15.0/packages.config +++ b/Build/15.0/packages.config @@ -3,6 +3,10 @@ + + + + diff --git a/Python/Product/LiveShare/LiveShare.csproj b/Python/Product/LiveShare/LiveShare.csproj new file mode 100644 index 0000000000..9c6794a3b6 --- /dev/null +++ b/Python/Product/LiveShare/LiveShare.csproj @@ -0,0 +1,116 @@ + + + + + + 15.0 + + + + + 14.0 + + + + + 16.0 + + + + + 16.0 + + + + + + Debug + AnyCPU + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60DC8134-EBA5-43B8-BCC9-BB4BC16C2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + Microsoft + Microsoft.PythonTools.LiveShare + {4065A3C8-0E5E-42AC-9D94-509AA90C90E9} + true + true + false + true + true + $(DefineConstants);$(SignedSym) + true + + + AnyCPU + + + + + + + + + + + {a85d479d-67a9-4bdb-904a-7d86daf68a6f} + Analysis + + + {fa7be5f5-e04f-4613-b7ac-70ce10d1bb68} + PythonTools + + + + + $(PackagesPath)\Microsoft.Cascade.LanguageServices.Common.0.3.536\lib\net461\Microsoft.Cascade.LanguageServices.Common.dll + + + $(PackagesPath)\Microsoft.Cascade.Common.0.3.536\lib\net461\Microsoft.Cascade.Common.dll + + + $(PackagesPath)\Microsoft.Cascade.Client.0.3.536\lib\net461\Microsoft.Cascade.Client.dll + + + $(PackagesPath)\Microsoft.VisualStudio.Cascade.Contracts.0.3.536\lib\net461\Microsoft.VisualStudio.Cascade.Contracts.dll + + + + + + $(PackagesPath)\Newtonsoft.Json\lib\net45\Newtonsoft.Json.dll + True + True + + + + + + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/Python/Product/LiveShare/PythonLanguageClient.cs b/Python/Product/LiveShare/PythonLanguageClient.cs new file mode 100644 index 0000000000..51317d473f --- /dev/null +++ b/Python/Product/LiveShare/PythonLanguageClient.cs @@ -0,0 +1,56 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +using System; +using System.Threading.Tasks; +using Microsoft.Cascade.Extensibility; +using Microsoft.Cascade.LanguageServices.Common; +using Microsoft.Cascade.LanguageServices.Contracts; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Threading; +using Task = System.Threading.Tasks.Task; + +namespace Microsoft +{ + internal class PythonLanguageClient : ICollaborationService, IAsyncDisposable + { + private static string[] PythonContentTypes = new string[] { "python" }; + private static DocumentFilter[] PythonDocumentFilters = new DocumentFilter[] + { + new DocumentFilter() { Language = "python" } + }; + private IAsyncDisposable languageServiceProviderService; + private SVsServiceProvider serviceProvider; + + public PythonLanguageClient(SVsServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + } + + internal async Task InitializeAsync(ILanguageServerHostService languageServerHostService) + { + if (languageServerHostService == null) + { + throw new ArgumentNullException(nameof(languageServerHostService)); + } + + var pythonLanguageServiceProviderCallback = new PythonLanguageServiceProviderCallback(this.serviceProvider); + this.languageServiceProviderService = await languageServerHostService.CreateCustomLanguageServerProviderAsync( + "languageServerProvider-python", + new LanguageServerProviderMetadata + { + IsLanguageClientProvider = false, + ContentTypes = PythonContentTypes, + DocumentFilters = PythonDocumentFilters + }, + pythonLanguageServiceProviderCallback, + null); + } + + public async Task DisposeAsync() + { + await this.languageServiceProviderService?.DisposeAsync(); + } + } +} diff --git a/Python/Product/LiveShare/PythonLanguageClientFactory.cs b/Python/Product/LiveShare/PythonLanguageClientFactory.cs new file mode 100644 index 0000000000..05910a7641 --- /dev/null +++ b/Python/Product/LiveShare/PythonLanguageClientFactory.cs @@ -0,0 +1,43 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +using System; +using System.ComponentModel.Composition; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Cascade.Client; +using Microsoft.Cascade.Extensibility; +using Microsoft.Cascade.LanguageServices.Common; +using Microsoft.VisualStudio.Shell; + +namespace Microsoft +{ + [ExportCollaborationService( + typeof(PythonLanguageClient), + Scope = SessionScope.Host, + Features = WellKnownFeatures.LspServices)] + internal class PythonLanguageClientFactory : ICollaborationServiceFactory + { + private readonly SVsServiceProvider serviceProvider; + + [ImportingConstructor] + public PythonLanguageClientFactory(SVsServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + } + + public async Task CreateServiceAsync(SessionContext sessionContext, CancellationToken cancellationToken) + { + var languageServerHostService = sessionContext.ServiceProvider.GetService(); + if (languageServerHostService == null) + { + return null; + } + + var pythonClient = new PythonLanguageClient(this.serviceProvider); + await pythonClient.InitializeAsync(languageServerHostService); + return pythonClient; + } + } +} diff --git a/Python/Product/LiveShare/PythonLanguageServiceProviderCallback.cs b/Python/Product/LiveShare/PythonLanguageServiceProviderCallback.cs new file mode 100644 index 0000000000..7ca6a63287 --- /dev/null +++ b/Python/Product/LiveShare/PythonLanguageServiceProviderCallback.cs @@ -0,0 +1,55 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Linq; +using Microsoft.Cascade.LanguageServices.Common; +using Microsoft.VisualStudio.LanguageServer.Protocol; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Threading; +using Microsoft.PythonTools.Editor; +using Microsoft.PythonTools.Intellisense; +using LS = Microsoft.PythonTools.Analysis.LanguageServer; +using Newtonsoft.Json.Linq; + +namespace Microsoft +{ + internal class PythonLanguageServiceProviderCallback : ILanguageServiceProviderCallback + { + private SVsServiceProvider serviceProvider; + + public PythonLanguageServiceProviderCallback(SVsServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + } + +#pragma warning disable 0067 + public event AsyncEventHandler NotifyAsync; +#pragma warning restore 0067 + + public async Task RequestAsync(LspRequest method, TIn param, CancellationToken cancellationToken) + { + if (method.Name == Methods.Initialize.Name) + { + var capabilities = new ServerCapabilities { CompletionProvider = new VisualStudio.LanguageServer.Protocol.CompletionOptions { TriggerCharacters = new[] { "." } } }; + object result = new InitializeResult { Capabilities = capabilities }; + return (TOut)(result); + } + if (method.Name == Methods.TextDocumentCompletion.Name) + { + var completionParams = param as CompletionParams; + var filePath = completionParams.TextDocument.Uri.LocalPath; + VsProjectAnalyzer analyzer = (await serviceProvider.FindAllAnalyzersForFile(filePath)).FirstOrDefault() as VsProjectAnalyzer; + + var lsCompletionParams = JObject.FromObject(completionParams).ToObject(); + object list = await analyzer.SendLanguageServerRequestAsync(method.Name, lsCompletionParams); + return (TOut)list; + } + + return default(TOut); + } + } +} \ No newline at end of file diff --git a/Python/Product/LiveShare/source.extension.vsixmanifest b/Python/Product/LiveShare/source.extension.vsixmanifest new file mode 100644 index 0000000000..265393cb37 --- /dev/null +++ b/Python/Product/LiveShare/source.extension.vsixmanifest @@ -0,0 +1,23 @@ + + + + Python - LiveShare + Provides LiveShare integration for Python projects + http://aka.ms/ptvs + http://aka.ms/ptvstutorial + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Python/Product/PythonTools/Properties/AssemblyInfo.cs b/Python/Product/PythonTools/Properties/AssemblyInfo.cs index 168909ebf1..984caa46fe 100644 --- a/Python/Product/PythonTools/Properties/AssemblyInfo.cs +++ b/Python/Product/PythonTools/Properties/AssemblyInfo.cs @@ -34,6 +34,7 @@ [assembly: InternalsVisibleTo("Microsoft.PythonTools.Uwp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.PythonTools.Workspace, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.PythonTools.Wsl, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("Microsoft.PythonTools.LiveShare, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("PythonToolsMockTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("DebuggerUITests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]