public void create_a_merged_workspace_filter() { var workspace1 = new WorkspaceFilter(); workspace1.AddFilter(new FixtureFilter() { Name = typeof(MathFixture).GetFixtureAlias(), Type = FilterType.Fixture }); var workspace2 = new WorkspaceFilter(); workspace2.AddFilter(new FixtureFilter() { Name = typeof(AnotherFixture).GetFixtureAlias(), Type = FilterType.Fixture }); var combined = new WorkspaceFilter(new WorkspaceFilter[] { workspace1, workspace2 }); var filter = combined.CreateTypeFilter(); filter.Matches(typeof(MathFixture)).ShouldBeTrue(); filter.Matches(typeof(AnotherFixture)).ShouldBeTrue(); filter.Matches(GetType()).ShouldBeFalse(); }
public WorkspaceSuite(string name) : base(name) { Filter = new WorkspaceFilter() { Name = name }; }
public void workspace_filter_returns_always_when_it_has_no_explicit_filters() { var workspace = new WorkspaceFilter(); workspace.FilterCount.ShouldEqual(0); workspace.Filters.ShouldHaveTheSameElementsAs(FixtureFilter.All()); }
public IEnumerable<IFixtureSelector> Organize(FixtureLibrary library, WorkspaceFilter workspace) { var namespaces = new Cache<string, NamespaceSelector>(ns => new NamespaceSelector(ns)); var fixtures = new Cache<string, FixtureSelector>(); // pass #1, collate the namespaces string[] names = getAllNamespaces(library, namespaces); var topLevels = collateNamespaces(namespaces, names); buildFixtureSelectors(library, namespaces, fixtures); selectFixtures(fixtures, workspace); selectNamespaces(namespaces, workspace); namespaces.Each(x => x.SetInitialState()); return topLevels.ToArray(); }
/// <summary> /// Filters a <paramref name="workspace"/> using <paramref name="modules"/>. /// </summary> /// <remarks> /// Currently only module filter is supported. /// </remarks> private WorkspaceDefinition ApplyModuleFilter(WorkspaceDefinition workspace, IReadOnlyList <StringId> modules) { using (var sw = Watch.Start()) { // WorkspaceFilter updates the existing workspace instead of creating brand new one. // This is crucial to avoid redundant type checking required for semantic workspace creation. var filter = new WorkspaceFilter(FrontEndContext.PathTable); WorkspaceDefinition filteredDefinition = filter.ApplyModuleFilter(workspace, modules); Logger.WorkspaceDefinitionFilteredBasedOnModuleFilter(LoggingContext, workspace.ModuleCount - filteredDefinition.ModuleCount, workspace.SpecCount - filteredDefinition.SpecCount, workspace.ModuleCount, filteredDefinition.ModuleCount, sw.ElapsedMilliseconds); return(filteredDefinition); } }
public void can_serialize_and_deserialize_a_workspace_filter() { var workspace = new WorkspaceFilter(); workspace.AddFilter(new FixtureFilter() { Name = typeof(MathFixture).GetFixtureAlias(), Type = FilterType.Fixture }); workspace.AddFilter(new FixtureFilter() { Name = typeof(AnotherFixture).GetFixtureAlias(), Type = FilterType.Fixture }); workspace.ShouldBeSerializable().ShouldBeOfType <WorkspaceFilter>().FilterCount.ShouldEqual(2); }
private List <ModuleDefinition> GetModulesAndSpecsToEvaluate(EvaluationFilter evaluationFilter) { if ( // Module filter can be applied without /enableIncrementalFrontEnd+ evaluationFilter.ModulesToResolve.Count != 0 || (evaluationFilter.CanPerformPartialEvaluationScript(PrimaryConfigFile) && FrontEndConfiguration.EnableIncrementalFrontEnd())) { var workspaceFilter = new WorkspaceFilter(FrontEndContext.PathTable); return(workspaceFilter.FilterForEvaluation(Workspace, evaluationFilter)); } // The prelude is never part of the build extent var allModules = Workspace.SpecModules.ToList(); // Under an Office build, the default source resolver defines the build extent. Otherwise, all modules are used var moduleExtent = FrontEndConfiguration.UseLegacyOfficeLogic() ? FindModulesConstitutingLegacyBuildExtent(allModules) : allModules; return(moduleExtent.Select(m => m.Definition).ToList()); }
/// <nodoc /> internal void FilterWorkspace(Workspace workspace, EvaluationFilter evaluationFilter) { if (!evaluationFilter.CanPerformPartialEvaluationScript(PrimaryConfigFile)) { return; } using (var sw = Watch.Start()) { int originalCount = workspace.SpecCount; // WorkspaceFilter updates the existing workspace instead of creating brand new one. // This is crucial to avoid redundant type checking required for semantic workspace creation. var filter = new WorkspaceFilter(FrontEndContext.PathTable); workspace.FilterWorkspace(filter.FilterForConversion(workspace, evaluationFilter)); Logger.WorkspaceFiltered(LoggingContext, workspace.SpecCount, originalCount, sw.ElapsedMilliseconds); } }
public IEnumerable <IFixtureSelector> Organize(FixtureLibrary library, WorkspaceFilter workspace) { var namespaces = new Cache <string, NamespaceSelector>(ns => new NamespaceSelector(ns)); var fixtures = new Cache <string, FixtureSelector>(); // pass #1, collate the namespaces string[] names = getAllNamespaces(library, namespaces); var topLevels = collateNamespaces(namespaces, names); buildFixtureSelectors(library, namespaces, fixtures); selectFixtures(fixtures, workspace); selectNamespaces(namespaces, workspace); namespaces.Each(x => x.SetInitialState()); return(topLevels.ToArray()); }
public void integrate_with_workspace_filter() { var workspace = new WorkspaceFilter(); workspace.AddFilter(new FixtureFilter() { Name = typeof(MathFixture).GetFixtureAlias(), Type = FilterType.Fixture }); workspace.AddFilter(new FixtureFilter() { Name = typeof(AnotherFixture).GetFixtureAlias(), Type = FilterType.Fixture }); var filter = workspace.CreateTypeFilter(); filter.Matches(typeof(MathFixture)).ShouldBeTrue(); filter.Matches(typeof(AnotherFixture)).ShouldBeTrue(); filter.Matches(GetType()).ShouldBeFalse(); }
/// <summary> /// Tries to filter a given workspace definition by reusing information from the previous BuildXL invocation. /// </summary> /// <returns> /// 1. Failure if the error occurred during parsing/binding one of the changed specs. /// 2. Result(null) when the filtering failed due to symbols mismatch or due to another reason. /// 3. Result(WorkspaceDefinition) when the filtering succeeded. /// </returns> /// <remarks> /// If the previous binding information can be reused, then the set of specs that are safe to use as public facades + serialized AST /// are identified as well /// </remarks> private async Task <FilteredWorkspaceDefinition> TryFilterWorkspaceDefinitionIncrementallyAsync( List <string> changedFiles, IWorkspaceProvider workspaceProvider, WorkspaceDefinition workspaceDefinition, EvaluationFilter evaluationFilter) { Logger.TryingToReuseFrontEndSnapshot(LoggingContext); // TODO: potentially, we could check the number of changes compared to the workspace definition size. // If the number of changes is too big, maybe we should go into the full parse mode. // But we need to check the perf implications before making this decision. var changedSpecs = changedFiles.Select( p => { var fullPath = AbsolutePath.Create(FrontEndContext.PathTable, p); var containingModule = workspaceDefinition.TryGetModuleDefinition(fullPath); return(new SpecWithOwningModule(fullPath, containingModule)); }).ToArray(); // Need to check if the spec does not belong to the current workspace // or the changed spec belongs to the prelude. foreach (var changedSpec in changedSpecs) { if (changedSpec.OwningModule == null) { Logger.FailToReuseFrontEndSnapshot( LoggingContext, I($"Changed spec file '{changedSpec.Path.ToString(FrontEndContext.PathTable)}' is not part of the computed workspace.")); return(FilteredWorkspaceDefinition.CanNotFilter()); } if (changedSpec.OwningModule.Descriptor == workspaceDefinition.PreludeModule.Descriptor) { Logger.FailToReuseFrontEndSnapshot( LoggingContext, I($"Changed spec file '{changedSpec.Path.ToString(FrontEndContext.PathTable)}' is part of the prelude.")); return(FilteredWorkspaceDefinition.CanNotFilter()); } } // Getting the snapshot from the previous run. // Binding snapshot contains all the specs as well as all the configuration files. // Need to adjust the count. var expectedNumberOfSpecs = workspaceDefinition.SpecCount + (workspaceProvider.GetConfigurationModule()?.Specs.Count ?? 0); var snapshot = FrontEndArtifactManager.TryLoadFrontEndSnapshot(expectedNumberOfSpecs); if (snapshot == null) { // The error message was already logged. return(FilteredWorkspaceDefinition.CanNotFilter()); } // Parsing and binding all the changed specs. var possibleParseResult = await workspaceProvider.ParseAndBindSpecsAsync(changedSpecs); var firstFailure = LogParseOrBindingErrorsIfAny(possibleParseResult); if (firstFailure != null) { // This is actual failure. // Instead of switching to the full mode, we can actually stop here. return(FilteredWorkspaceDefinition.Error(firstFailure)); } // Snapshot is valid and parse/binding is completed successfully. var snapshotState = GetSnapshotReuseState(possibleParseResult, snapshot); if (snapshotState.State == SnapshotState.NoMatch) { // NoMatch is returned if the snapshot is unavailable. if (snapshotState.SpecsWithIncompatiblePublicSurface.Count != 0) { Logger.FailToReuseFrontEndSnapshot( LoggingContext, I($"Spec file '{snapshotState.SpecsWithIncompatiblePublicSurface.First().Path.AbsolutePath}' changed its binding symbols.")); } return(FilteredWorkspaceDefinition.CanNotFilter()); } // Changed file could get different symbols. // Need to re-save it within the front-end snapshot. UpdateAndSaveSnapshot(possibleParseResult, snapshot); var snapshotProvider = new SnapshotBasedSpecProvider(snapshot); // Now we know exactly which are all the files that need to go through parsing/type checking/AST conversion. So we // inform that to the artifact manager so the public surface and AST serialization // can be resued for the rest, if available. // Observe these set of files are not reflecting a potential user filter, but that's fine. If there is a dirty spec // that is outside of the filter, that spec won't be requested by the workspace anyway NotifyDirtySpecsForPublicFacadeAndAstReuse( snapshotProvider, workspaceDefinition, changedSpecs.Select(f => f.Path).ToList()); // The fingerprints for all changed specs are still the same, // so we can filter the workspace definition provided that the filter allows it. if (snapshotState.State == SnapshotState.FullMatch) { var filter = new WorkspaceFilter(FrontEndContext.PathTable); var filteredWorkspace = evaluationFilter.CanPerformPartialEvaluationScript(PrimaryConfigFile) ? filter.FilterWorkspaceDefinition(workspaceDefinition, evaluationFilter, snapshotProvider) : workspaceDefinition.Modules; return(FilteredWorkspaceDefinition.Filter(new WorkspaceDefinition(filteredWorkspace, workspaceDefinition.PreludeModule))); } // Specs are not the same, but we would be able to load public facades for all unaffected specs. var dirtySpecNames = string.Join( ", ", snapshotState.SpecsWithTheSamePublicSurface.Take(10).Select(p => Path.GetFileName(p.Path.AbsolutePath))); Logger.FailedToFilterWorkspaceDefinition( LoggingContext, I($"{dirtySpecNames} changed one or more declarations.")); return(FilteredWorkspaceDefinition.CanNotFilter()); }
public IEnumerable <IStartupActionSelector> GetActionSelectors(FixtureLibrary library, WorkspaceFilter filter) { return(library.StartupActions.Select(x => new StartupActionSelector(x, filter.StartupActions.Contains(x))).ToArray()); }
public FixtureAssembly(IProject project) { _systemTypeName = project.SystemTypeName; _fixtureAssembly = project.FixtureAssembly; _filter = project.CurrentFixtureFilter(); }
private void selectNamespaces(Cache <string, NamespaceSelector> namespaces, WorkspaceFilter workspace) { workspace.Filters.Where(x => x.Type == FilterType.Namespace).Each(x => namespaces[x.Name].Select(true)); }
private void selectNamespaces(Cache<string, NamespaceSelector> namespaces, WorkspaceFilter workspace) { workspace.Filters.Where(x => x.Type == FilterType.Namespace).Each(x => namespaces[x.Name].Select(true)); }
private void selectFixtures(Cache<string, FixtureSelector> fixtures, WorkspaceFilter workspace) { workspace.Filters .Where(x => x.Type == FilterType.Fixture) .Each(x => fixtures.WithValue(x.Name, selector => selector.Select(true))); }
private void selectFixtures(Cache <string, FixtureSelector> fixtures, WorkspaceFilter workspace) { workspace.Filters .Where(x => x.Type == FilterType.Fixture) .Each(x => fixtures.WithValue(x.Name, selector => selector.Select(true))); }
private void FilterWorkspace(Workspace workspace, EvaluationFilter filter) { var workspaceFilter = new WorkspaceFilter(m_pathTable); workspace.FilterWorkspace(workspaceFilter.FilterForConversion(workspace, filter)); }
public IEnumerable<IStartupActionSelector> GetActionSelectors(FixtureLibrary library, WorkspaceFilter filter) { return library.StartupActions.Select(x => new StartupActionSelector(x, filter.StartupActions.Contains(x))).ToArray(); }