private void UpdateDropDownsSynchronously(CancellationToken cancellationToken) { AssertIsForeground(); // If the presenter already has the full list and the model is already complete, then we // don't have to do any further computation nor push anything to the presenter if (PresenterAlreadyHaveUpToDateFullList(cancellationToken)) { return; } // We need to ensure that all the state computation is up to date, so cancel any // previous work and ensure the model is up to date StartModelUpdateAndSelectedItemUpdateTasks(modelUpdateDelay: 0, selectedItemUpdateDelay: 0, updateUIWhenDone: false); // Wait for the work to be complete. We'll wait with our cancellationToken, so if the // user hits cancel we won't block them, but the computation can still continue //using (Logger.LogBlock(FunctionId.NavigationBar_UpdateDropDownsSynchronously_WaitForModel, cancellationToken)) { _modelTask.Wait(cancellationToken); } //using (Logger.LogBlock(FunctionId.NavigationBar_UpdateDropDownsSynchronously_WaitForSelectedItemInfo, cancellationToken)) { _selectedItemInfoTask.Wait(cancellationToken); } _presenter.PresentItems( _modelTask.Result.Types, _selectedItemInfoTask.Result.TypeItem, _selectedItemInfoTask.Result.MemberItem); _versionStampOfFullListPushedToPresenter = _modelTask.Result.SemanticVersionStamp; }
public void SetOutput(RazorCSharpDocument csharpDocument, DefaultDocumentSnapshot document) { lock (_setOutputLock) { if (!document.TryGetTextVersion(out var version)) { Debug.Fail("The text version should have already been evaluated."); return; } if (_sourceVersion.HasValue && _sourceVersion == SourceVersion.GetNewerVersion(version)) { // Latest document is newer than the provided document. return; } if (!document.TryGetText(out var source)) { Debug.Fail("The text should have already been evaluated."); return; } _source = source; _sourceVersion = version; _output = csharpDocument; _latestDocument = document; _textContainer.SetText(SourceText.From(Output.GeneratedCode)); } }
public void SetOutput( DefaultDocumentSnapshot document, RazorCSharpDocument outputCSharp, RazorHtmlDocument outputHtml, VersionStamp inputVersion, VersionStamp outputCSharpVersion, VersionStamp outputHtmlVersion) { lock (_setOutputLock) { if (_inputVersion.HasValue && _inputVersion != inputVersion && _inputVersion == _inputVersion.Value.GetNewerVersion(inputVersion)) { // Latest document is newer than the provided document. return; } if (!document.TryGetText(out var source)) { Debug.Fail("The text should have already been evaluated."); return; } _source = source; _inputVersion = inputVersion; _outputCSharpVersion = outputCSharpVersion; _outputHtmlVersion = outputHtmlVersion; _outputCSharp = outputCSharp; _outputHtml = outputHtml; _latestDocument = document; _csharpTextContainer.SetText(SourceText.From(_outputCSharp.GeneratedCode)); _htmlTextContainer.SetText(SourceText.From(_outputHtml.GeneratedHtml)); } }
public ProjectAttributes With( VersionStamp?version = null, string?name = null, string?assemblyName = null, string?language = null, Optional <string?> filePath = default, Optional <string?> outputPath = default, Optional <string?> outputRefPath = default, Optional <CompilationOutputFilePaths> compilationOutputPaths = default, Optional <string?> defaultNamespace = default, Optional <bool> isSubmission = default, Optional <bool> hasAllInformation = default, Optional <bool> runAnalyzers = default) { var newVersion = version ?? Version; var newName = name ?? Name; var newAssemblyName = assemblyName ?? AssemblyName; var newLanguage = language ?? Language; var newFilepath = filePath.HasValue ? filePath.Value : FilePath; var newOutputPath = outputPath.HasValue ? outputPath.Value : OutputFilePath; var newOutputRefPath = outputRefPath.HasValue ? outputRefPath.Value : OutputRefFilePath; var newCompilationOutputPaths = compilationOutputPaths.HasValue ? compilationOutputPaths.Value : CompilationOutputFilePaths; var newDefaultNamespace = defaultNamespace.HasValue ? defaultNamespace.Value : DefaultNamespace; var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : IsSubmission; var newHasAllInformation = hasAllInformation.HasValue ? hasAllInformation.Value : HasAllInformation; var newRunAnalyzers = runAnalyzers.HasValue ? runAnalyzers.Value : RunAnalyzers; if (newVersion == Version && newName == Name && newAssemblyName == AssemblyName && newLanguage == Language && newFilepath == FilePath && newOutputPath == OutputFilePath && newOutputRefPath == OutputRefFilePath && newCompilationOutputPaths == CompilationOutputFilePaths && newDefaultNamespace == DefaultNamespace && newIsSubmission == IsSubmission && newHasAllInformation == HasAllInformation && newRunAnalyzers == RunAnalyzers) { return(this); } return(new ProjectAttributes( Id, newVersion, newName, newAssemblyName, newLanguage, newFilepath, newOutputPath, newOutputRefPath, newCompilationOutputPaths, newDefaultNamespace, newIsSubmission, newHasAllInformation, newRunAnalyzers)); }
// Internal for testing internal DocumentState( HostWorkspaceServices services, HostDocument hostDocument, SourceText text, VersionStamp?version, Func <Task <TextAndVersion> > loader) { Services = services; HostDocument = hostDocument; _sourceText = text; _version = version; _loader = loader; _lock = new object(); }
public ProjectAttributes With( VersionStamp?version = default, string name = null, string assemblyName = null, string language = null, Optional <string> filePath = default, Optional <string> outputPath = default, Optional <string> outputRefPath = default, Optional <string> defaultNamespace = default, Optional <bool> isSubmission = default, Optional <bool> hasAllInformation = default) { var newVersion = version.HasValue ? version.Value : Version; var newName = name ?? Name; var newAssemblyName = assemblyName ?? AssemblyName; var newLanguage = language ?? Language; var newFilepath = filePath.HasValue ? filePath.Value : FilePath; var newOutputPath = outputPath.HasValue ? outputPath.Value : OutputFilePath; var newOutputRefPath = outputRefPath.HasValue ? outputRefPath.Value : OutputRefFilePath; var newDefaultNamespace = defaultNamespace.HasValue ? defaultNamespace.Value : DefaultNamespace; var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : IsSubmission; var newHasAllInformation = hasAllInformation.HasValue ? hasAllInformation.Value : HasAllInformation; if (newVersion == Version && newName == Name && newAssemblyName == AssemblyName && newLanguage == Language && newFilepath == FilePath && newOutputPath == OutputFilePath && newOutputRefPath == OutputRefFilePath && newDefaultNamespace == DefaultNamespace && newIsSubmission == IsSubmission && newHasAllInformation == HasAllInformation) { return(this); } return(new ProjectAttributes( Id, newVersion, newName, newAssemblyName, newLanguage, newFilepath, newOutputPath, newOutputRefPath, newDefaultNamespace, newIsSubmission, newHasAllInformation)); }
private TestDocumentState( HostWorkspaceServices services, HostDocument hostDocument, SourceText text, VersionStamp?version, Func <Task <TextAndVersion> > loader, Action onTextChange, Action onTextLoaderChange, Action onConfigurationChange, Action onWorkspaceProjectChange) : base(services, hostDocument, text, version, loader) { _onTextChange = onTextChange; _onTextLoaderChange = onTextLoaderChange; _onConfigurationChange = onConfigurationChange; _onWorkspaceProjectChange = onWorkspaceProjectChange; }
public SolutionAttributes With( VersionStamp?version = null, Optional <string?> filePath = default, Optional <Guid> telemetryId = default) { var newVersion = version ?? Version; var newFilePath = filePath.HasValue ? filePath.Value : FilePath; var newTelemetryId = telemetryId.HasValue ? telemetryId.Value : TelemetryId; if (newVersion == Version && newFilePath == FilePath && newTelemetryId == TelemetryId) { return(this); } return(new SolutionAttributes(Id, newVersion, newFilePath, newTelemetryId)); }
private void PushSelectedItemsToPresenter(NavigationBarSelectedTypeAndMember selectedItems) { AssertIsForeground(); var oldLeft = selectedItems.TypeItem; var oldRight = selectedItems.MemberItem; NavigationBarItem newLeft = null; NavigationBarItem newRight = null; var listOfLeft = new List <NavigationBarItem>(); var listOfRight = new List <NavigationBarItem>(); if (oldRight != null) { newRight = new NavigationBarPresentedItem(oldRight.Text, oldRight.Glyph, oldRight.Spans, oldRight.ChildItems, oldRight.Bolded, oldRight.Grayed || selectedItems.ShowMemberItemGrayed) { TrackingSpans = oldRight.TrackingSpans }; listOfRight.Add(newRight); } if (oldLeft != null) { newLeft = new NavigationBarPresentedItem(oldLeft.Text, oldLeft.Glyph, oldLeft.Spans, listOfRight, oldLeft.Bolded, oldLeft.Grayed || selectedItems.ShowTypeItemGrayed) { TrackingSpans = oldLeft.TrackingSpans }; listOfLeft.Add(newLeft); } IList <NavigationBarProjectItem> projectItems; NavigationBarProjectItem selectedProjectItem; GetProjectItems(out projectItems, out selectedProjectItem); _presenter.PresentItems( projectItems, selectedProjectItem, listOfLeft, newLeft, newRight); _versionStampOfFullListPushedToPresenter = null; }
public bool TrySetOutput( DefaultDocumentSnapshot document, RazorCodeDocument codeDocument, VersionStamp inputVersion, VersionStamp outputCSharpVersion, VersionStamp outputHtmlVersion) { lock (_setOutputLock) { if (_inputVersion.HasValue && _inputVersion.Value != inputVersion && _inputVersion == _inputVersion.Value.GetNewerVersion(inputVersion)) { // Latest document is newer than the provided document. return(false); } if (!document.TryGetText(out var source)) { Debug.Fail("The text should have already been evaluated."); return(false); } _source = source; _inputVersion = inputVersion; _outputCSharpVersion = outputCSharpVersion; _outputHtmlVersion = outputHtmlVersion; _outputCSharp = codeDocument.GetCSharpDocument(); _outputHtml = codeDocument.GetHtmlDocument(); _latestDocument = document; var csharpSourceText = codeDocument.GetCSharpSourceText(); _csharpTextContainer.SetText(csharpSourceText); var htmlSourceText = codeDocument.GetHtmlSourceText(); _htmlTextContainer.SetText(htmlSourceText); return(true); } }
public static async Task <ProjectAnalysisData> CreateAsync(Project project, IEnumerable <StateSet> stateSets, bool avoidLoadingData, CancellationToken cancellationToken) { VersionStamp?version = null; var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, AnalysisResult>(); foreach (var stateSet in stateSets) { var state = stateSet.GetProjectState(project.Id); var result = await state.GetAnalysisDataAsync(project, avoidLoadingData, cancellationToken).ConfigureAwait(false); Contract.ThrowIfFalse(project.Id == result.ProjectId); if (!version.HasValue) { if (result.Version != VersionStamp.Default) { version = result.Version; } } else { // all version must be same or default (means not there yet) Contract.Requires(version == result.Version || result.Version == VersionStamp.Default); } builder.Add(stateSet.Analyzer, result); } if (!version.HasValue) { // there is no saved data to return. return(new ProjectAnalysisData(project.Id, VersionStamp.Default, ImmutableDictionary <DiagnosticAnalyzer, AnalysisResult> .Empty)); } return(new ProjectAnalysisData(project.Id, version.Value, builder.ToImmutable())); }
public static async Task <ProjectAnalysisData> CreateAsync(IPersistentStorageService persistentService, Project project, IEnumerable <StateSet> stateSets, bool avoidLoadingData, CancellationToken cancellationToken) { VersionStamp?version = null; var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResult>(); foreach (var stateSet in stateSets) { var state = stateSet.GetOrCreateProjectState(project.Id); var result = await state.GetAnalysisDataAsync(persistentService, project, avoidLoadingData, cancellationToken).ConfigureAwait(false); Contract.ThrowIfFalse(project.Id == result.ProjectId); if (!version.HasValue) { version = result.Version; } else if (version.Value != VersionStamp.Default && version.Value != result.Version) { // if not all version is same, set version as default. // this can happen at the initial data loading or // when document is closed and we put active file state to project state version = VersionStamp.Default; } builder.Add(stateSet.Analyzer, result); } if (!version.HasValue) { // there is no saved data to return. return(new ProjectAnalysisData(project.Id, VersionStamp.Default, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty)); } return(new ProjectAnalysisData(project.Id, version.Value, builder.ToImmutable())); }
private ProjectInfo With( ProjectId id = null, VersionStamp?version = default(VersionStamp?), string name = null, string assemblyName = null, string language = null, Optional <string> filePath = default(Optional <string>), Optional <string> outputPath = default(Optional <string>), CompilationOptions compilationOptions = null, ParseOptions parseOptions = null, IEnumerable <DocumentInfo> documents = null, IEnumerable <ProjectReference> projectReferences = null, IEnumerable <MetadataReference> metadataReferences = null, IEnumerable <AnalyzerReference> analyzerReferences = null, Optional <bool> isSubmission = default(Optional <bool>), Optional <Type> hostObjectType = default(Optional <Type>)) { var newId = id ?? this.Id; var newVersion = version.HasValue ? version.Value : this.Version; var newName = name ?? this.Name; var newAssemblyName = assemblyName ?? this.AssemblyName; var newLanguage = language ?? this.Language; var newFilepath = filePath.HasValue ? filePath.Value : this.FilePath; var newOutputPath = outputPath.HasValue ? outputPath.Value : this.OutputFilePath; var newCompilationOptions = compilationOptions ?? this.CompilationOptions; var newParseOptions = parseOptions ?? this.ParseOptions; var newDocuments = documents ?? this.Documents; var newProjectReferences = projectReferences ?? this.ProjectReferences; var newMetadataReferences = metadataReferences ?? this.MetadataReferences; var newAnalyzerReferences = analyzerReferences ?? this.AnalyzerReferences; var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : this.IsSubmission; var newHostObjectType = hostObjectType.HasValue ? hostObjectType.Value : this.HostObjectType; if (newId == this.Id && newVersion == this.Version && newName == this.Name && newAssemblyName == this.AssemblyName && newLanguage == this.Language && newFilepath == this.FilePath && newOutputPath == this.OutputFilePath && newCompilationOptions == this.CompilationOptions && newParseOptions == this.ParseOptions && newDocuments == this.Documents && newProjectReferences == this.ProjectReferences && newMetadataReferences == this.MetadataReferences && newAnalyzerReferences == this.AnalyzerReferences && newIsSubmission == this.IsSubmission && newHostObjectType == this.HostObjectType) { return(this); } return(new ProjectInfo( newId, newVersion, newName, newAssemblyName, newLanguage, newFilepath, newOutputPath, newCompilationOptions, newParseOptions, newDocuments, newProjectReferences, newMetadataReferences, newAnalyzerReferences, newIsSubmission, newHostObjectType)); }
public DefaultProjectSnapshot(HostProject hostProject, Project workspaceProject, VersionStamp?version = null) { if (hostProject == null) { throw new ArgumentNullException(nameof(hostProject)); } HostProject = hostProject; WorkspaceProject = workspaceProject; // Might be null FilePath = hostProject.FilePath; Version = version ?? VersionStamp.Default; }
private void UpdateDropDownsSynchronously(CancellationToken cancellationToken) { AssertIsForeground(); // If the presenter already has the full list and the model is already complete, then we // don't have to do any further computation nor push anything to the presenter if (PresenterAlreadyHaveUpToDateFullList(cancellationToken)) { return; } // We need to ensure that all the state computation is up to date, so cancel any // previous work and ensure the model is up to date StartModelUpdateAndSelectedItemUpdateTasks(modelUpdateDelay: 0, selectedItemUpdateDelay: 0, updateUIWhenDone: false); // Wait for the work to be complete. We'll wait with our cancellationToken, so if the // user hits cancel we won't block them, but the computation can still continue using (Logger.LogBlock(FunctionId.NavigationBar_UpdateDropDownsSynchronously_WaitForModel, cancellationToken)) { _modelTask.Wait(cancellationToken); } using (Logger.LogBlock(FunctionId.NavigationBar_UpdateDropDownsSynchronously_WaitForSelectedItemInfo, cancellationToken)) { _selectedItemInfoTask.Wait(cancellationToken); } IList<NavigationBarProjectItem> projectItems; NavigationBarProjectItem selectedProjectItem; GetProjectItems(out projectItems, out selectedProjectItem); _presenter.PresentItems( projectItems, selectedProjectItem, _modelTask.Result.Types, _selectedItemInfoTask.Result.TypeItem, _selectedItemInfoTask.Result.MemberItem); _versionStampOfFullListPushedToPresenter = _modelTask.Result.SemanticVersionStamp; }
internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments( IEnumerable <AbstractProject> projects) { AssertIsForeground(); // If the workspace host isn't actually ready yet, we shouldn't do anything. // Also, if the solution is closing we shouldn't do anything either, because all of our state is // in the process of going away. This can happen if we receive notification that a document has // opened in the middle of the solution close operation. if (!this.HostReadyForEvents || _tracker._solutionIsClosing) { return; } // We need to push these projects and any project dependencies we already know about. Therefore, compute the // transitive closure of the projects that haven't already been pushed, keeping them in appropriate order. var visited = new HashSet <AbstractProject>(); var inOrderToPush = new List <AbstractProject>(); foreach (var project in projects) { AddToPushListIfNeeded(project, inOrderToPush, visited); } var projectInfos = inOrderToPush.Select(p => p.CreateProjectInfoForCurrentState()).ToImmutableArray(); // We need to enable projects to start pushing changes to workspace hosts even before we add the solution/project to the host. // This is required because between the point we capture the project info for current state and the point where we start pushing to workspace hosts, // project system may send new events on the AbstractProject on a background thread, and these won't get pushed over to the workspace hosts as we didn't set the _pushingChangesToWorkspaceHost flag on the AbstractProject. // By invoking StartPushingToWorkspaceHosts upfront, any project state changes on the background thread will enqueue notifications to workspace hosts on foreground scheduled tasks. foreach (var project in inOrderToPush) { project.StartPushingToWorkspaceHosts(); } if (!_solutionAdded) { string solutionFilePath = null; VersionStamp?version = default(VersionStamp?); // Figure out the solution version if (ErrorHandler.Succeeded(_tracker._vsSolution.GetSolutionInfo(out var solutionDirectory, out var solutionFileName, out var userOptsFile)) && solutionFileName != null) { solutionFilePath = Path.Combine(solutionDirectory, solutionFileName); if (File.Exists(solutionFilePath)) { version = VersionStamp.Create(File.GetLastWriteTimeUtc(solutionFilePath)); } } if (version == null) { version = VersionStamp.Create(); } var id = SolutionId.CreateNewId(string.IsNullOrWhiteSpace(solutionFileName) ? null : solutionFileName); _tracker.RegisterSolutionProperties(id); var solutionInfo = SolutionInfo.Create(id, version.Value, solutionFilePath, projects: projectInfos); this.Host.OnSolutionAdded(solutionInfo); _solutionAdded = true; } else { // The solution is already added, so we'll just do project added notifications from here foreach (var projectInfo in projectInfos) { this.Host.OnProjectAdded(projectInfo); } } foreach (var project in inOrderToPush) { _pushedProjects.Add(project); foreach (var document in project.GetCurrentDocuments()) { if (document.IsOpen) { this.Host.OnDocumentOpened( document.Id, document.GetOpenTextBuffer(), isCurrentContext: LinkedFileUtilities.IsCurrentContextHierarchy(document, _tracker._runningDocumentTable)); } } } }
private void PushSelectedItemsToPresenter(NavigationBarSelectedTypeAndMember selectedItems) { AssertIsForeground(); var oldLeft = selectedItems.TypeItem; var oldRight = selectedItems.MemberItem; NavigationBarItem newLeft = null; NavigationBarItem newRight = null; var listOfLeft = new List<NavigationBarItem>(); var listOfRight = new List<NavigationBarItem>(); if (oldRight != null) { newRight = new NavigationBarPresentedItem(oldRight.Text, oldRight.Glyph, oldRight.Spans, oldRight.ChildItems, oldRight.Bolded, oldRight.Grayed || selectedItems.ShowMemberItemGrayed); newRight.TrackingSpans = oldRight.TrackingSpans; listOfRight.Add(newRight); } if (oldLeft != null) { newLeft = new NavigationBarPresentedItem(oldLeft.Text, oldLeft.Glyph, oldLeft.Spans, listOfRight, oldLeft.Bolded, oldLeft.Grayed || selectedItems.ShowTypeItemGrayed); newLeft.TrackingSpans = oldLeft.TrackingSpans; listOfLeft.Add(newLeft); } IList<NavigationBarProjectItem> projectItems; NavigationBarProjectItem selectedProjectItem; GetProjectItems(out projectItems, out selectedProjectItem); _presenter.PresentItems( projectItems, selectedProjectItem, listOfLeft, newLeft, newRight); _versionStampOfFullListPushedToPresenter = null; }