/// <summary> /// Handles the <see cref="IActiveConfiguredProjectSubscriptionService"/> callback on the active configured project's /// design-time build change notification service. /// </summary> private async Task ProjectBuildRuleBlock_ChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e) { await ThreadingService.SwitchToUIThread(); using (ProjectAsynchronousTasksService.LoadedProject()) { foreach (var resolvedReferenceChange in e.Value.ProjectChanges.Values) { if (!WatchedDesignTimeBuildRules.Contains(resolvedReferenceChange.After.RuleName)) { // This is an evaluation rule. continue; } foreach (string resolvedReferencePath in resolvedReferenceChange.Difference.AddedItems) { // If this is a resolved project reference, we need to treat it specially. string originalItemSpec = resolvedReferenceChange.After.Items[resolvedReferencePath]["OriginalItemSpec"]; if (!string.IsNullOrEmpty(originalItemSpec)) { if (e.Value.CurrentState[ProjectReference.SchemaName].Items.ContainsKey(originalItemSpec)) { string originalFullPath = UnconfiguredProject.MakeRooted(originalItemSpec); ProjectReferenceState state; if (!_projectReferenceFullPaths.TryGetValue(originalFullPath, out state)) { _projectReferenceFullPaths = _projectReferenceFullPaths.Add(originalFullPath, state = new ProjectReferenceState()); } state.ResolvedPath = resolvedReferencePath; // Be careful to not add assembly references that overlap with project references. if (state.AsProjectReference) { continue; } } } Marshal.ThrowExceptionForHR(_intellisenseEngine.AddAssemblyReference(resolvedReferencePath)); } foreach (string resolvedReferencePath in resolvedReferenceChange.Difference.RemovedItems) { Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveAssemblyReference(resolvedReferencePath)); } Marshal.ThrowExceptionForHR(_intellisenseEngine.StartIntellisenseEngine()); } } }
/// <summary> /// Handles the <see cref="IActiveConfiguredProjectSubscriptionService"/> callback event on the active configured project's /// change notification service. /// </summary> private async System.Threading.Tasks.Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e) { await ThreadingService.SwitchToUIThread(); await ProjectAsynchronousTasksService.LoadedProjectAsync(async delegate { var sourceFiles = e.Value.ProjectChanges[CSharp.SchemaName]; var projectReferences = e.Value.ProjectChanges[ProjectReference.SchemaName]; #pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770) var treeUpdate = await ProjectTreeService.PublishLatestTreeAsync(blockDuringLoadingTree: true); #pragma warning restore CA2007 // Do not directly await a Task var tree = treeUpdate.Tree; foreach (var sourceUnit in sourceFiles.Difference.AddedItems.Select(item => SourceFileToLanguageServiceUnit(item, tree)).Where(u => u != null)) { Marshal.ThrowExceptionForHR(_intellisenseEngine.AddFile(sourceUnit.Item1, sourceUnit.Item2)); } foreach (var sourceUnit in sourceFiles.Difference.RemovedItems.Select(item => SourceFileToLanguageServiceUnit(item, tree)).Where(u => u != null)) { Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveFile(sourceUnit.Item1, sourceUnit.Item2)); } foreach (KeyValuePair <string, string> sourceFileNames in sourceFiles.Difference.RenamedItems) { var newSourceUnit = SourceFileToLanguageServiceUnit(sourceFileNames.Value, tree); if (newSourceUnit != null) { string beforeAbsolutePath = UnconfiguredProject.MakeRooted(sourceFileNames.Key); Marshal.ThrowExceptionForHR(_intellisenseEngine.RenameFile(beforeAbsolutePath, newSourceUnit.Item1, newSourceUnit.Item2)); } } foreach (string projectReferencePath in projectReferences.Difference.AddedItems) { string projectReferenceFullPath = UnconfiguredProject.MakeRooted(projectReferencePath); ProjectReferenceState state; if (!_projectReferenceFullPaths.TryGetValue(projectReferenceFullPath, out state)) { _projectReferenceFullPaths = _projectReferenceFullPaths.Add(projectReferenceFullPath, state = new ProjectReferenceState()); } IVsIntellisenseProject intellisenseProject; if (LanguageServiceRegister.TryGetIntellisenseProject(projectReferenceFullPath, out intellisenseProject)) { if (state.ResolvedPath != null && !state.AsProjectReference) { Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveAssemblyReference(state.ResolvedPath)); } state.AsProjectReference = true; Marshal.ThrowExceptionForHR(_intellisenseEngine.AddP2PReference(intellisenseProject)); } } foreach (string projectReferencePath in projectReferences.Difference.RemovedItems) { string projectReferenceFullPath = UnconfiguredProject.MakeRooted(projectReferencePath); _projectReferenceFullPaths = _projectReferenceFullPaths.Remove(projectReferenceFullPath); IVsIntellisenseProject intellisenseProject; if (LanguageServiceRegister.TryGetIntellisenseProject(projectReferencePath, out intellisenseProject)) { Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveP2PReference(_intellisenseEngine)); } ProjectReferenceState state; if (_projectReferenceFullPaths.TryGetValue(projectReferenceFullPath, out state)) { state.AsProjectReference = false; } } Marshal.ThrowExceptionForHR(_intellisenseEngine.StartIntellisenseEngine()); }); }