예제 #1
0
        private async Task <Workspace> BuildAndFilterWorkspaceAsync(WorkspaceDefinition workspaceDefinition, IWorkspaceProvider workspaceProvider, FrontEndEngineAbstraction engineAbstraction, EvaluationFilter evaluationFilter)
        {
            // First, trying to filter workspace based on information from the previous run
            var possibleFilteredWorkspace = await TryCreateFilteredWorkspaceAsync(workspaceDefinition, workspaceProvider, engineAbstraction, evaluationFilter);

            if (!possibleFilteredWorkspace.Succeeded)
            {
                // Error was already logged
                return(Workspace.Failure(workspaceProvider, workspaceProvider.Configuration, possibleFilteredWorkspace.Failure));
            }

            // If the filtered workspace is not null, just return it.
            // Otherwise falling back to the full parse mode.
            if (possibleFilteredWorkspace.Result != null)
            {
                return(possibleFilteredWorkspace.Result);
            }

            // "Incremental" workspace construction has failed, but we still can try to use module filter to build a smaller workspace.
            if (evaluationFilter.ModulesToResolve.Count != 0)
            {
                var filteredDefinition = this.ApplyModuleFilter(workspaceDefinition, evaluationFilter.ModulesToResolve);
                return(await workspaceProvider.CreateWorkspaceAsync(filteredDefinition, userFilterWasApplied : true));
            }

            Logger.BuildingFullWorkspace(LoggingContext);
            return(await workspaceProvider.CreateWorkspaceAsync(workspaceDefinition, userFilterWasApplied : false));
        }
예제 #2
0
 /// <inheritdoc />
 public async Task <Workspace> CreateWorkspaceAsync(WorkspaceDefinition workspaceDefinition, bool userFilterWasApplied)
 {
     using (m_statistics.EndToEndParsing.Start())
     {
         return(await m_decoratee.CreateWorkspaceAsync(workspaceDefinition, userFilterWasApplied));
     }
 }
예제 #3
0
        /// <summary>
        /// Tries to create a filtered workspace based on a front-end snapshot from the previous BuildXL invocation.
        /// </summary>
        /// <returns>
        /// * Possibke&lt;ValidConstructedWorkspace&gt; when the workspace was successfully constructed.
        /// * Possible&lt;null&gt; when the snapshot was unaiable.
        /// * Failure when the snapshot was available but parsing failed.
        /// </returns>
        private async Task <Possible <Workspace> > TryCreateFilteredWorkspaceAsync(Possible <WorkspaceDefinition> workspaceDefinition, IWorkspaceProvider workspaceProvider, FrontEndEngineAbstraction engineAbstraction, EvaluationFilter evaluationFilter)
        {
            if (!FrontEndConfiguration.ConstructAndSaveBindingFingerprint())
            {
                Logger.FailToReuseFrontEndSnapshot(
                    LoggingContext,
                    "Binding fingerprint is disabled. Please use 'constructAndSaveBindingFingerprint' option to turn it on");
                return(default(Possible <Workspace>));
            }

            // If a filter cannot be performed and public facade + AST is not to be used, then there is no point in continuing and we can
            // go to full mode
            if (!evaluationFilter.CanPerformPartialEvaluationScript(PrimaryConfigFile) && !CanUseSpecPublicFacadeAndAst())
            {
                var message = !CanUseSpecPublicFacadeAndAst()
                    ? "Engine state was not reloaded"
                    : "User filter was not specified";
                Logger.FailToReuseFrontEndSnapshot(LoggingContext, message);
                return(default(Possible <Workspace>));
            }

            var changedFiles = engineAbstraction.GetChangedFiles()?.ToList();

            if (changedFiles == null)
            {
                Logger.FailToReuseFrontEndSnapshot(LoggingContext, "Change journal is not available");
                return(default(Possible <Workspace>));
            }

            using (var sw = Watch.Start())
            {
                // We're potentially in incremental mode.
                var filteredDefinitionResult = await TryFilterWorkspaceDefinitionIncrementallyAsync(
                    changedFiles,
                    workspaceProvider,
                    workspaceDefinition.Result,
                    evaluationFilter);

                if (filteredDefinitionResult.Failed)
                {
                    return(filteredDefinitionResult.Failure);
                }

                if (filteredDefinitionResult.Filtered)
                {
                    var filteredDefinition = filteredDefinitionResult.FilteredDefinition;
                    Logger.WorkspaceDefinitionFiltered(
                        LoggingContext,
                        filteredDefinition.SpecCount,
                        workspaceDefinition.Result.SpecCount,
                        sw.ElapsedMilliseconds);

                    // TODO: with C# 7, use tuple instead of changing the workspace to carry the information about the filtering.
                    return(await workspaceProvider.CreateWorkspaceAsync(filteredDefinition, userFilterWasApplied : true));
                }
            }

            return(default(Possible <Workspace>));
        }