/// <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>)); }
private void UpdateAndSaveSnapshot(Possible <ISourceFile>[] parseResults, IWorkspaceBindingSnapshot snapshot) { if (!FrontEndConfiguration.ConstructAndSaveBindingFingerprint()) { return; } foreach (var sourceFile in parseResults) { ISourceFile source = sourceFile.Result; Contract.Assert(source.BindingSymbols != null, "source.BindingSymbols != null"); snapshot.UpdateBindingFingerprint( source.GetAbsolutePath(FrontEndContext.PathTable), source.BindingSymbols.ReferencedSymbolsFingerprint, source.BindingSymbols.DeclaredSymbolsFingerprint); } SaveFrontEndSnapshot(snapshot); }