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)); }
/// <inheritdoc /> public async Task <Workspace> CreateWorkspaceAsync(WorkspaceDefinition workspaceDefinition, bool userFilterWasApplied) { using (m_statistics.EndToEndParsing.Start()) { return(await m_decoratee.CreateWorkspaceAsync(workspaceDefinition, userFilterWasApplied)); } }
/// <summary> /// Tries to create a filtered workspace based on a front-end snapshot from the previous BuildXL invocation. /// </summary> /// <returns> /// * Possibke<ValidConstructedWorkspace> when the workspace was successfully constructed. /// * Possible<null> 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>)); }