public DefaultProjectHierarchyProxy(
            CollaborationSession session,
            JoinableTaskFactory joinableTaskFactory)
        {
            if (session is null)
            {
                throw new ArgumentNullException(nameof(session));
            }

            if (joinableTaskFactory is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskFactory));
            }

            _session             = session;
            _joinableTaskFactory = joinableTaskFactory;
        }
예제 #2
0
        public void MultipleExitCalls()
        {
            EasyCollaboration    target  = new EasyCollaboration(context);
            CollaborationSession session = target.StartCollaboration();

            Assert.IsNotNull(session);
            target.ExitCollaboration();
            target.ExitCollaboration();
            target.ExitCollaboration();
            target.ExitCollaboration();
            target  = new EasyCollaboration(context, null, null);
            session = target.StartCollaboration();
            Assert.IsNotNull(session);
            target.ExitCollaboration();
            target.ExitCollaboration();
            target.ExitCollaboration();
            target.ExitCollaboration();
        }
예제 #3
0
        public Task <ICollaborationService> CreateServiceAsync(CollaborationSession session, CancellationToken cancellationToken)
        {
            if (session == null)
            {
                throw new ArgumentNullException(nameof(session));
            }

            var serializer = (JsonSerializer)session.GetService(typeof(JsonSerializer));

            serializer.Converters.RegisterRazorLiveShareConverters();

            var razorLanguageServices  = _workspace.Services.GetLanguageServices(RazorLanguage.Name);
            var projectSnapshotManager = razorLanguageServices.GetRequiredService <ProjectSnapshotManager>();

            var service = new DefaultProjectSnapshotManagerProxy(session, _foregroundDispatcher, projectSnapshotManager, _joinableTaskContext.Factory);

            return(Task.FromResult <ICollaborationService>(service));
        }
        public async Task SetSession(CollaborationSession session)
        {
            _session = session;
            var roots = await session.ListRootsAsync(CancellationToken.None).ConfigureAwait(false);

            if (roots.Length > 0)
            {
                _remoteRootPath = session.ConvertSharedUriToLocalPath(roots[0]);
                _remoteRootPath = _remoteRootPath.Substring(0, _remoteRootPath.Length - 1);
                var lastSlash = _remoteRootPath.LastIndexOf('\\');
                _externalPath  = _remoteRootPath.Substring(0, lastSlash + 1);
                _externalPath += "~external";
            }
            IsRemoteSession = true;
            session.RemoteServicesChanged += (object sender, RemoteServicesChangedEventArgs e) =>
            {
                _remoteDiagnosticListTable.UpdateWorkspaceDiagnosticsPresent(_session.RemoteServiceNames.Contains("workspaceDiagnostics"));
            };
        }
        // Today we ensure that all _ViewImports in the shared project exist on the guest because we don't currently track import documents
        // in a manner that would allow us to retrieve/monitor that data across the wire. Once the Razor sub-system is moved to use
        // DocumentSnapshots we'll be able to rely on that API to more properly manage files that impact parsing of Razor documents.
        private async Task EnsureViewImportsCopiedAsync(CollaborationSession sessionContext, CancellationToken cancellationToken)
        {
            var listDirectoryOptions = new ListDirectoryOptions()
            {
                Recursive       = true,
                IncludePatterns = new[] { "*.cshtml" }
            };

            var copyTasks = new List <Task>();
            var roots     = await sessionContext.ListRootsAsync(cancellationToken);

            foreach (var root in roots)
            {
                var fileUris = await sessionContext.ListDirectoryAsync(root, listDirectoryOptions, cancellationToken);

                StartViewImportsCopy(fileUris, copyTasks, sessionContext, cancellationToken);
            }

            await Task.WhenAll(copyTasks);
        }
예제 #6
0
        public Task <ICollaborationService> CreateServiceAsync(CollaborationSession sessionContext, CancellationToken cancellationToken)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException(nameof(sessionContext));
            }

            var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            _viewImportsCopyTask = EnsureViewImportsCopiedAsync(sessionContext, cts.Token);

            _sessionAccessor.SetSession(sessionContext);
            var sessionDetector = new SessionActiveDetector(() =>
            {
                cts.Cancel();
                _sessionAccessor.SetSession(session: null);
            });

            return(Task.FromResult <ICollaborationService>(sessionDetector));
        }
        public Task <ICollaborationService> CreateServiceAsync(CollaborationSession sessionContext, CancellationToken cancellationToken)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException(nameof(sessionContext));
            }

#pragma warning disable CA2000 // Dispose objects before losing scope
            var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
#pragma warning restore CA2000 // Dispose objects before losing scope
            _viewImportsCopyTask = EnsureViewImportsCopiedAsync(sessionContext, cts.Token);

            _sessionAccessor.SetSession(sessionContext);
            var sessionDetector = new SessionActiveDetector(() =>
            {
                cts.Cancel();
                _sessionAccessor.SetSession(session: null);
            });
            return(Task.FromResult <ICollaborationService>(sessionDetector));
        }
예제 #8
0
 public void ExitCollaboration()
 {
     lock (_locker)
     {
         try
         {
             DeactivateConsumer();
             DeactivateObserver();
             Logger.Info("Collaboration finished");
         }
         finally
         {
             _subsId     = 0;
             _obsId      = 0;
             _theSession = null;
             _consumer   = null;
             _observer   = null;
             _collabs    = null;
             _sessions   = null;
         }
     }
 }
        public async Task <ICollaborationService> CreateServiceAsync(CollaborationSession collaborationSession, CancellationToken cancellationToken)
        {
            await LoadRoslynPackageAsync(cancellationToken).ConfigureAwait(false);

            await _remoteLanguageServiceWorkspace.SetSessionAsync(collaborationSession).ConfigureAwait(false);

            // Kick off loading the projects in the background.
            // Clients can call EnsureProjectsLoadedAsync to await completion.
            LoadProjectsAsync(CancellationToken.None).Forget();

            var lifeTimeService = new RemoteLanguageServiceSession();

            lifeTimeService.Disposed += (s, e) =>
            {
                _remoteLanguageServiceWorkspace.EndSession();
                CloseAllProjects();
                _remoteLanguageServiceWorkspace.Dispose();
                _projectsLoadedTaskCompletionSource = new TaskCompletionSource <bool>();
            };

            return(lifeTimeService);
        }
예제 #10
0
        public async Task <ICollaborationService> CreateServiceAsync(CollaborationSession sessionContext, CancellationToken cancellationToken)
        {
            // This collaboration service depends on these serializers being immediately available so we need to register these now so the
            // guest project snapshot manager can retrieve the hosts project state.
            var serializer = (JsonSerializer)sessionContext.GetService(typeof(JsonSerializer));

            serializer.Converters.RegisterRazorLiveShareConverters();

            var languageServices = _workspace.Services.GetLanguageServices(RazorLanguage.Name);
            var projectManager   = (ProjectSnapshotManagerBase)languageServices.GetRequiredService <ProjectSnapshotManager>();

            var projectSnapshotManagerProxy = await sessionContext.GetRemoteServiceAsync <IProjectSnapshotManagerProxy>(typeof(IProjectSnapshotManagerProxy).Name, cancellationToken);

            var synchronizationService = new ProjectSnapshotSynchronizationService(
                _joinableTaskContext.Factory,
                sessionContext,
                projectSnapshotManagerProxy,
                projectManager);

            await synchronizationService.InitializeAsync(cancellationToken);

            return(synchronizationService);
        }
        public DefaultProjectHierarchyProxy(
            CollaborationSession session,
            ForegroundDispatcher foregroundDispatcher,
            JoinableTaskFactory joinableTaskFactory)
        {
            if (session == null)
            {
                throw new ArgumentNullException(nameof(session));
            }

            if (foregroundDispatcher == null)
            {
                throw new ArgumentNullException(nameof(foregroundDispatcher));
            }

            if (joinableTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(joinableTaskFactory));
            }

            _session = session;
            _foregroundDispatcher = foregroundDispatcher;
            _joinableTaskFactory  = joinableTaskFactory;
        }
예제 #12
0
        public Task <ICollaborationService> CreateServiceAsync(CollaborationSession collaborationSession, CancellationToken cancellationToken)
        {
            var languageServerGuestService = (LS.ILanguageServerGuestService)collaborationSession.GetService(typeof(LS.ILanguageServerGuestService));

            collaborationSession.RemoteServicesChanged += (sender, e) =>
            {
                // VS will expose a roslyn LSP server.
                var roslynLspServerProviderName = LanguageServicesUtils.GetLanguageServerProviderServiceName(StringConstants.RoslynProviderName);
                // Newer versions of VS will expose language specific LSP servers for Roslyn.
                var languageSpecificLspServerProviderName = LanguageServicesUtils.GetLanguageServerProviderServiceName(LanguageSpecificProviderName);
                // VSCode will expose a "any" LSP provider and both support roslyn languages.
                var anyLspServerProviderName = LanguageServicesUtils.GetLanguageServerProviderServiceName(StringConstants.AnyProviderName);

                // For VS, Preferentially use the language specific server when it's available, otherwise fall back to the generic roslyn server.
                if (collaborationSession.RemoteServiceNames.Contains(languageSpecificLspServerProviderName))
                {
                    ActiveLanguageServerClient = languageServerGuestService.CreateLanguageServerClient(languageSpecificLspServerProviderName);
                }
                else if (collaborationSession.RemoteServiceNames.Contains(roslynLspServerProviderName))
                {
                    ActiveLanguageServerClient = languageServerGuestService.CreateLanguageServerClient(roslynLspServerProviderName);
                }
                else if (collaborationSession.RemoteServiceNames.Contains(anyLspServerProviderName))
                {
                    ActiveLanguageServerClient = languageServerGuestService.CreateLanguageServerClient(anyLspServerProviderName);
                }
            };

            // Register Roslyn supported capabilities
            languageServerGuestService.RegisterClientMetadata(
                new string[] { StringConstants.TypeScriptLanguageName },
                new LS.LanguageServerClientMetadata(
                    true,
                    JObject.FromObject(new ServerCapabilities
            {
                // Uses Roslyn client.
                DocumentSymbolProvider = true,

                // Uses LSP SDK client.
                DocumentLinkProvider             = null,
                RenameProvider                   = false,
                DocumentOnTypeFormattingProvider = null,
                DocumentRangeFormattingProvider  = false,
                DocumentFormattingProvider       = false,
                CodeLensProvider                 = null,
                CodeActionProvider               = false,
                ExecuteCommandProvider           = null,
                WorkspaceSymbolProvider          = false,
                DocumentHighlightProvider        = false,
                ReferencesProvider               = false,
                DefinitionProvider               = false,
                SignatureHelpProvider            = null,
                CompletionProvider               = null,
                HoverProvider    = false,
                TextDocumentSync = null,
            })));

            languageServerGuestService.RegisterClientMetadata(
                new string[] { StringConstants.CSharpLspContentTypeName, StringConstants.VBLspLanguageName },
                new LS.LanguageServerClientMetadata(
                    true,
                    JObject.FromObject(new ServerCapabilities
            {
                // Uses Roslyn client.
                DocumentOnTypeFormattingProvider = new DocumentOnTypeFormattingOptions(),
                DocumentRangeFormattingProvider  = true,
                DocumentFormattingProvider       = true,
                DocumentSymbolProvider           = true,
                CodeActionProvider        = true,
                ExecuteCommandProvider    = new ExecuteCommandOptions(),
                DocumentHighlightProvider = true,
                ReferencesProvider        = true,
                DefinitionProvider        = true,
                SignatureHelpProvider     = new SignatureHelpOptions()
                {
                },
                CompletionProvider     = new CompletionOptions(),
                ImplementationProvider = true,

                // Uses LSP SDK client.
                DocumentLinkProvider    = null,
                RenameProvider          = false,
                CodeLensProvider        = null,
                WorkspaceSymbolProvider = false,
                HoverProvider           = false,
                TextDocumentSync        = null,
            })));

            var lifeTimeService = LspClientLifeTimeService;

            lifeTimeService.Disposed += (s, e) =>
            {
                ActiveLanguageServerClient?.Dispose();
                ActiveLanguageServerClient = null;
            };

            return(Task.FromResult <ICollaborationService>(lifeTimeService));
        }
 public Task <ICollaborationService> CreateServiceAsync(CollaborationSession session, CancellationToken cancellationToken)
 {
     return(Task.FromResult <ICollaborationService>(new RemoteHierarchyService(session, ThreadHelper.JoinableTaskFactory)));
 }
 public System.Threading.Tasks.Task <ICollaborationService> CreateServiceAsync(
     CollaborationSession collaborationSession, CancellationToken cancellationToken)
 {
     return(System.Threading.Tasks.Task.FromResult <ICollaborationService>(new CollaborationHostService(collaborationSession, _eventAggregator)));
 }
        private static async Task <(ImmutableHashSet <string> remoteRootPaths, ImmutableHashSet <string> externalPaths)> GetLocalPathsOfRemoteRootsAsync(CollaborationSession session)
        {
            var roots = await session.ListRootsAsync(CancellationToken.None).ConfigureAwait(false);

            var localPathsOfRemoteRoots = roots.Select(root => session.ConvertSharedUriToLocalPath(root)).ToImmutableArray();

            var remoteRootPaths = ImmutableHashSet.CreateBuilder <string>();
            var externalPaths   = ImmutableHashSet.CreateBuilder <string>();

            foreach (var localRoot in localPathsOfRemoteRoots)
            {
                // The local root is something like tmp\\xxx\\<workspace name>
                // The external root should be tmp\\xxx\\~external, so replace the workspace name with ~external.
#pragma warning disable CS8602 // Dereference of a possibly null reference. (Can localRoot be null here?)
                var splitRoot = localRoot.TrimEnd('\\').Split('\\');
#pragma warning restore CS8602 // Dereference of a possibly null reference.
                splitRoot[splitRoot.Length - 1] = "~external";
                var externalPath = string.Join("\\", splitRoot) + "\\";

                remoteRootPaths.Add(localRoot);
                externalPaths.Add(externalPath);
            }

            return(remoteRootPaths.ToImmutable(), externalPaths.ToImmutable());
        }
예제 #16
0
 public CollaborationHostService(CollaborationSession collaborationSession, IEventAggregator eventAggregator)
 {
     eventAggregator.Publish(new LiveShareStartedEvent(collaborationSession));
 }
 public void SetSession(CollaborationSession session)
 {
     _guestSessionIsActive = session != null;
     _currentSession       = session;
 }
 private static void StartViewImportsCopy(Uri[] fileUris, List <Task> copyTasks, CollaborationSession sessionContext, CancellationToken cancellationToken)
 {
     foreach (var fileUri in fileUris)
     {
         if (fileUri.GetAbsoluteOrUNCPath().EndsWith(ViewImportsFileName, StringComparison.Ordinal))
         {
             var copyTask = sessionContext.DownloadFileAsync(fileUri, cancellationToken);
             copyTasks.Add(copyTask);
         }
     }
 }
예제 #19
0
 public LiveShareStartedEvent(CollaborationSession collaborationSession)
 {
     CollaborationSession = collaborationSession;
 }