예제 #1
0
        /// <summary>
        /// Creates the BuildXL workspace and initializes the language service providers.
        /// </summary>
        /// <remarks>
        /// This must be called when a text document is actually opened. The order VSCode
        /// calls the plugin is "Initialize" -> "DidConfigurationChange" -> DidOpenTextDocument.
        /// So, if you attempt to create the workspace, and initialize the providers during the
        /// initialization phase, then you will not have proper access to any configuration settings
        /// the user may have made.
        /// </remarks>
        private Task <(WorkspaceLoadingState workspaceLoadingState, AppState appState, LanguageServiceProviders languageServiceProviders)> LoadWorkspaceAsync(TextDocumentManager documentManager = null)
        {
            var workspaceLoadingTask = m_workspaceLoadingTask.GetOrCreate(async() =>
            {
                var result = await Task.Run(() =>
                {
                    try
                    {
                        m_progressReporter.ReportWorkspaceInit();

                        WorkspaceLoadingState workspaceLoadingState;

                        if (m_rootUri == null)
                        {
                            throw new ArgumentException("Root directory was not passed from VSCode via the rootUri configuration value");
                        }

                        var appState = AppState.TryCreateWorkspace(documentManager, m_rootUri, (s, ea) =>
                        {
                            // "Casting" the EventArgs object from the BuildXL library to the "local" version
                            // to avoid pulling in all of its dependencies during build.
                            var rpcEventArgs = BuildXL.Ide.JsonRpc.WorkspaceProgressEventArgs.Create(
                                (BuildXL.Ide.JsonRpc.ProgressStage)ea.ProgressStage,
                                ea.NumberOfProcessedSpecs,
                                ea.TotalNumberOfSpecs);
                            m_progressReporter.ReportWorkspaceInProgress(WorkspaceLoadingParams.InProgress(rpcEventArgs));
                        },
                                                                   m_testContext,
                                                                   m_settings);

                        if (appState == null || appState.HasUnrecoverableFailures())
                        {
                            workspaceLoadingState = WorkspaceLoadingState.Failure;
                            m_progressReporter.ReportWorkspaceFailure(m_tracer.LogFilePath, OpenLogFile);
                        }
                        else
                        {
                            workspaceLoadingState = WorkspaceLoadingState.Success;

                            m_progressReporter.ReportWorkspaceSuccess();
                        }

                        LanguageServiceProviders providers = null;

                        lock (m_loadWorkspaceLock)
                        {
                            if (workspaceLoadingState == WorkspaceLoadingState.Success)
                            {
                                // In practice you should not make callouts while holding
                                // a lock. Initializing the providers sets members of this
                                // class and also relies on members of the app-state.
                                // So, we do want to block callers until initialization of
                                // the providers is complete, however, be warned that
                                // if a provider ever calls back into the app it could
                                // cause a deadlock.
                                providers = InitializeProviders(appState);
                            }
                        }

                        return(workspaceLoadingState, appState, providers);
                    }
                    catch (Exception e)
                    {
                        var errorMessage = e.ToStringDemystified();
                        Logger.LanguageServerUnhandledInternalError(LoggingContext, errorMessage);
                        m_progressReporter.ReportWorkspaceFailure(m_tracer.LogFilePath, OpenLogFile);
                        m_testContext.GetValueOrDefault().ErrorReporter?.Invoke(errorMessage);
                        return(WorkspaceLoadingState.Failure, (AppState)null, (LanguageServiceProviders)null);
                    }
                });

                return(result);
            });

            // Changing the workspace loading state once the task is finished.
            workspaceLoadingTask.ContinueWith(t =>
            {
                m_workspaceLoadingState = t.Result.Item1;
            });

            return(workspaceLoadingTask);
        }
예제 #2
0
 public void ReportWorkspaceInProgress(WorkspaceLoadingParams workspcaeLoading)
 {
 }