internal async Task OnProjectChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e = null)
        {
            bool isDebuggable = await _launchProviders.Value.IsDebuggableAsync()
                                .ConfigureAwait(false);

            if (isDebuggable)
            {
                // If we're already registered, the service no-ops
                _startupProjectsListService.AddProject(ref _projectGuid);
            }
            else
            {
                // If we're already unregistered, the service no-ops
                _startupProjectsListService.RemoveProject(ref _projectGuid);
            }
        }
Beispiel #2
0
        public Task ApplyProjectEndBatchAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> update, CancellationToken cancellationToken)
        {
            Requires.NotNull(update, nameof(update));

            VerifyInitializedAndNotDisposed();

            if (update.Value.ProjectChanges.TryGetValue(ProjectBuildRuleName, out IProjectChangeDescription projectChange) &&
                projectChange.Difference.AnyChanges)
            {
                IComparable version = GetConfiguredProjectVersion(update);

                ProcessProjectUpdateHandlers(version, update, cancellationToken);
            }

            return(Task.CompletedTask);
        }
        private async Task OnProjectChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> update)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            await InitializeAsync().ConfigureAwait(false);

            // when TargetFrameworks or TargetFrameworkMoniker changes, reset subscriptions so that
            // any new configured projects are picked up
            if (HasTargetFrameworkChanged(update))
            {
                await ResetSubscriptions().ConfigureAwait(false);
            }
        }
        private async Task OnProjectChangedCoreAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e, RuleHandlerType handlerType)
        {
            // TODO: https://github.com/dotnet/roslyn-project-system/issues/353
            await _commonServices.ThreadingService.SwitchToUIThread();

            await _tasksService.LoadedProjectAsync(async() =>
            {
                await HandleAsync(e, handlerType).ConfigureAwait(false);
            });

            // If "TargetFrameworks" property has changed, we need to refresh the project context and subscriptions.
            if (HasTargetFrameworksChanged(e))
            {
                await UpdateProjectContextAndSubscriptionsAsync().ConfigureAwait(false);
            }
        }
            private void OnActiveConfigurationsChanged(IProjectVersionedValue <IConfigurationGroup <ConfiguredProject> > e)
            {
                if (IsDisposing || IsDisposed)
                {
                    return;
                }

                // Clean up past subscriptions
                _designTimeBuildSubscriptionLink?.Dispose();

                if (e.Value.Count > 0)
                {
                    var sourceLinkOptions = new StandardRuleDataflowLinkOptions
                    {
                        RuleNames           = s_designTimeBuildWatchedRules,
                        PropagateCompletion = true
                    };

                    var disposableBag = new DisposableBag(CancellationToken.None);
                    // We are taking source blocks from multiple configured projects and creating a SyncLink to combine the sources.
                    // The SyncLink will only publish data when the versions of the sources match. There is a problem with that.
                    // The sources have some version components that will make this impossible to match across TFMs. We introduce a
                    // intermediate block here that will remove those version components so that the synclink can actually sync versions.
                    IEnumerable <ProjectDataSources.SourceBlockAndLink <IProjectValueVersions> > sourceBlocks = e.Value.Select(
                        cp =>
                    {
                        IReceivableSourceBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> > sourceBlock = cp.Services.ProjectSubscription.JointRuleSource.SourceBlock;
                        IPropagatorBlock <IProjectVersionedValue <IProjectSubscriptionUpdate>, IProjectVersionedValue <IProjectSubscriptionUpdate> > versionDropper = CreateVersionDropperBlock();
                        disposableBag.AddDisposable(sourceBlock.LinkTo(versionDropper, sourceLinkOptions));
                        return(versionDropper.SyncLinkOptions <IProjectValueVersions>(sourceLinkOptions));
                    });

                    Action <Tuple <ImmutableList <IProjectValueVersions>, TIdentityDictionary> > action = ProjectPropertyChanged;
                    var target = new ActionBlock <Tuple <ImmutableList <IProjectValueVersions>, TIdentityDictionary> >(action);

                    var targetLinkOptions = new DataflowLinkOptions {
                        PropagateCompletion = true
                    };

                    ImmutableList <ProjectDataSources.SourceBlockAndLink <IProjectValueVersions> > sourceBlocksAndCapabilitiesOptions = sourceBlocks.ToImmutableList()
                                                                                                                                        .Insert(0, _projectVsServices.Project.Capabilities.SourceBlock.SyncLinkOptions <IProjectValueVersions>());

                    disposableBag.AddDisposable(ProjectDataSources.SyncLinkTo(sourceBlocksAndCapabilitiesOptions, target, targetLinkOptions));

                    _designTimeBuildSubscriptionLink = disposableBag;
                }
            }
Beispiel #7
0
        private async Task OnProjectChanged(IProjectVersionedValue <IProjectSubscriptionUpdate> e, RuleHandlerType handlerType)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            await InitializeAsync().ConfigureAwait(false);

            // TODO: https://github.com/dotnet/roslyn-project-system/issues/353
            await _commonServices.ThreadingService.SwitchToUIThread();

            using (_tasksService.LoadedProject())
            {
                await HandleAsync(e, handlerType).ConfigureAwait(false);
            }
        }
            internal async Task OnInputsChangedAsync(IProjectVersionedValue <PackageRestoreUnconfiguredInput> e)
            {
                // No configurations - likely during project close
                if (e.Value.RestoreInfo is null)
                {
                    return;
                }

                try
                {
                    await RestoreAsync(e.Value.RestoreInfo);
                }
                finally
                {
                    OnRestoreCompleted(e);
                }
            }
        public async Task HandleAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e, IProjectChangeDescription projectChange)
        {
            Requires.NotNull(e, nameof(e));
            Requires.NotNull(projectChange, nameof(projectChange));

            IProjectChangeDiff diff = projectChange.Difference;

            foreach (string filePath in diff.RemovedItems)
            {
                // Item includes are always relative to csproj/vbproj
                string fullPath = _project.MakeRooted(filePath);

                RemoveSourceFile(fullPath);
            }

            if (diff.AddedItems.Count > 0 || diff.RenamedItems.Count > 0 || diff.ChangedItems.Count > 0)
            {
                // Make sure the tree matches the same version of the evaluation that we're handling
                IProjectTreeServiceState treeState = await _projectTree.TreeService.PublishTreeAsync(e.ToRequirements(), blockDuringLoadingTree : true)
                                                     .ConfigureAwait(true);                               // TODO: https://github.com/dotnet/roslyn-project-system/issues/353

                foreach (string filePath in diff.AddedItems)
                {
                    string fullPath = _project.MakeRooted(filePath);

                    AddSourceFile(fullPath, treeState);
                }

                foreach (KeyValuePair <string, string> filePaths in diff.RenamedItems)
                {
                    string beforeFullPath = _project.MakeRooted(filePaths.Key);
                    string afterFullPath  = _project.MakeRooted(filePaths.Value);

                    RemoveSourceFile(beforeFullPath);
                    AddSourceFile(afterFullPath, treeState);
                }

                foreach (string filePath in diff.ChangedItems)
                {   // We add and then remove ChangedItems to handle Linked metadata changes
                    string fullPath = _project.MakeRooted(filePath);

                    RemoveSourceFile(fullPath);
                    AddSourceFile(fullPath);
                }
            }
        }
Beispiel #10
0
        internal void OnChanged(IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectSubscriptionUpdate, IProjectItemSchema> > e)
        {
            lock (_stateLock)
            {
                if (_link == null)
                {
                    // We've been unloaded, so don't update the state (which will be empty)
                    return;
                }

                _state = _state.Update(
                    jointRuleUpdate: e.Value.Item1,
                    sourceItemsUpdate: e.Value.Item2,
                    projectItemSchema: e.Value.Item3,
                    configuredProjectVersion: e.DataSourceVersions[ProjectDataSources.ConfiguredProjectVersion]);
            }
        }
Beispiel #11
0
        private Task ItemsChangedAsync(IProjectVersionedValue <IProjectCatalogSnapshot> snapshot)
        {
            SubmitTreeUpdateAsync(
                (treeSnapshot, configuredProjectExports, cancellationToken) =>
            {
                var dependenciesNode = treeSnapshot.Value.Tree;

                if (!cancellationToken.IsCancellationRequested)
                {
                    dependenciesNode = BuildTree(dependenciesNode, snapshot.Value, cancellationToken);
                }

                return(Task.FromResult(new TreeUpdateResult(dependenciesNode, false)));
            });

            return(Task.CompletedTask);
        }
        public async Task ApplyProjectBuildAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> update, bool isActiveContext, CancellationToken cancellationToken)
        {
            Requires.NotNull(update, nameof(update));

            VerifyInitializedAndNotDisposed();

            IProjectChangeDescription projectChange = update.Value.ProjectChanges[ProjectBuildRuleName];

            if (projectChange.Difference.AnyChanges)
            {
                IComparable version = GetConfiguredProjectVersion(update);

                ProcessOptions(projectChange.After);
                await ProcessCommandLineAsync(version, projectChange.Difference, isActiveContext, cancellationToken);
                ProcessProjectBuildFailure(projectChange.After);
            }
        }
Beispiel #13
0
        private Task OnConfiguredProjectEvaluatedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e)
        {
            // If "TargetFrameworks" property has changed, we need to refresh the project context and subscriptions.
            if (HasTargetFrameworksChanged())
            {
                return(UpdateProjectContextAndSubscriptionsAsync());
            }

            return(Task.CompletedTask);

            bool HasTargetFrameworksChanged()
            {
                // remember actual property value and compare
                return(e.Value.ProjectChanges.TryGetValue(ConfigurationGeneral.SchemaName, out IProjectChangeDescription projectChange) &&
                       (projectChange.Difference.ChangedProperties.Contains(ConfigurationGeneral.TargetFrameworkProperty) ||
                        projectChange.Difference.ChangedProperties.Contains(ConfigurationGeneral.TargetFrameworksProperty)));
            }
        }
        private async Task OnProjectChangedCoreAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e, RuleHandlerType handlerType)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            await _tasksService.LoadedProjectAsync(async() =>
            {
                await HandleAsync(e, handlerType).ConfigureAwait(false);
            });

            // If "TargetFramework" or "TargetFrameworks" property has changed, we need to refresh the project context and subscriptions.
            if (HasTargetFrameworksChanged(e))
            {
                await UpdateProjectContextAndSubscriptionsAsync().ConfigureAwait(false);
            }
        }
        private Task ProcessProjectEvaluationHandlersAsync(IComparable version, IProjectVersionedValue<IProjectSubscriptionUpdate> update, bool isActiveContext, CancellationToken cancellationToken)
        {
            foreach (ExportLifetimeContext<IWorkspaceContextHandler> handler in _handlers)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (handler.Value is IProjectEvaluationHandler evaluationHandler)
                {
                    IProjectChangeDescription projectChange = update.Value.ProjectChanges[evaluationHandler.ProjectEvaluationRule];
                    if (!projectChange.Difference.AnyChanges)
                        continue;

                    evaluationHandler.Handle(version, projectChange, isActiveContext, _logger);
                }
            }

            return Task.CompletedTask;
        }
Beispiel #16
0
        [InlineData(false)]     // Project Build
        public async Task OnProjectChangedAsync_PassesProjectUpdate(bool evaluation)
        {
            IProjectVersionedValue <IProjectSubscriptionUpdate> updateResult = null;

            void applyChanges(IProjectVersionedValue <IProjectSubscriptionUpdate> u, bool _, CancellationToken __)
            {
                updateResult = u;
            }

            var applyChangesToWorkspaceContext = evaluation ? IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectEvaluationAsync(applyChanges) : IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectBuildAsync(applyChanges);

            var instance = await CreateInitializedInstanceAsync(applyChangesToWorkspaceContext : applyChangesToWorkspaceContext);

            var update = IProjectVersionedValueFactory.CreateEmpty();
            await instance.OnProjectChangedAsync(update, evaluation);

            Assert.Same(updateResult, update);
        }
Beispiel #17
0
        private async Task ProcessDesignTimeInputs(IProjectVersionedValue <DesignTimeInputs> input)
        {
            DesignTimeInputs designTimeInputs = input.Value;

            IVsAsyncFileChangeEx?vsAsyncFileChangeEx = await _fileChangeService.GetValueAsync();

            Assumes.Present(vsAsyncFileChangeEx);

            // we don't care about the difference between types of inputs, so we just construct one hashset for fast comparisons later
            var allFiles = new HashSet <string>(StringComparers.Paths);

            allFiles.AddRange(designTimeInputs.Inputs);
            allFiles.AddRange(designTimeInputs.SharedInputs);

            // Remove any files we're watching that we don't care about any more
            var removedFiles = new List <string>();

            foreach ((string file, uint cookie) in _fileWatcherCookies)
            {
                if (!allFiles.Contains(file))
                {
                    await vsAsyncFileChangeEx.UnadviseFileChangeAsync(cookie);

                    removedFiles.Add(file);
                }
            }

            foreach (string file in removedFiles)
            {
                _fileWatcherCookies.Remove(file);
            }

            // Now watch and output files that are new
            foreach (string file in allFiles)
            {
                if (!_fileWatcherCookies.ContainsKey(file))
                {
                    // We don't care about delete and add here, as they come through data flow, plus they are really bouncy - every file change is a Time, Del and Add event)
                    uint cookie = await vsAsyncFileChangeEx.AdviseFileChangeAsync(file, _VSFILECHANGEFLAGS.VSFILECHG_Time | _VSFILECHANGEFLAGS.VSFILECHG_Size, sink : this);

                    _fileWatcherCookies.Add(file, cookie);
                }
            }
        }
        private async Task OnProjectChangedAsync(
            IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCatalogSnapshot> > e,
            RuleHandlerType handlerType)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            await _tasksService.LoadedProjectAsync(async() =>
            {
                if (_tasksService.UnloadCancellationToken.IsCancellationRequested)
                {
                    return;
                }

                await HandleAsync(e, handlerType).ConfigureAwait(false);
            });
        }
        internal async Task OnProjectChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e = null)
        {
            bool isDebuggable = await _launchProviders.Value.IsDebuggableAsync();

            IVsStartupProjectsListService startupProjectsListService = await _startupProjectsListService.GetValueAsync();

            Assumes.Present(startupProjectsListService);

            if (isDebuggable)
            {
                // If we're already registered, the service no-ops
                startupProjectsListService.AddProject(ref _projectGuid);
            }
            else
            {
                // If we're already unregistered, the service no-ops
                startupProjectsListService.RemoveProject(ref _projectGuid);
            }
        }
        // Internal for testing
        internal async Task OnProjectChanged(IProjectVersionedValue <IProjectSubscriptionUpdate> update)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            await CommonServices.TasksService.LoadedProjectAsync(async() =>
            {
                await ExecuteWithLock(async() =>
                {
                    string mvcReferenceFullPath = null;
                    var references = update.Value.CurrentState[ResolvedCompilationReference.SchemaName].Items;
                    foreach (var reference in references)
                    {
                        if (reference.Key.EndsWith(MvcAssemblyFileName, StringComparison.OrdinalIgnoreCase))
                        {
                            mvcReferenceFullPath = reference.Key;
                            break;
                        }
                    }

                    if (mvcReferenceFullPath == null)
                    {
                        // Ok we can't find an MVC version. Let's assume this project isn't using Razor then.
                        await UpdateProjectUnsafeAsync(null).ConfigureAwait(false);
                        return;
                    }

                    var version = GetAssemblyVersion(mvcReferenceFullPath);
                    if (version == null)
                    {
                        // Ok we can't find an MVC version. Let's assume this project isn't using Razor then.
                        await UpdateProjectUnsafeAsync(null).ConfigureAwait(false);
                        return;
                    }

                    var configuration = FallbackRazorConfiguration.SelectConfiguration(version);
                    var hostProject   = new HostProject(CommonServices.UnconfiguredProject.FullPath, configuration);
                    await UpdateProjectUnsafeAsync(hostProject).ConfigureAwait(false);
                });
            }, registerFaultHandler : true);
        }
Beispiel #21
0
 protected async Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCapabilitiesSnapshot> > projectSnapshot)
 {
     if (projectSnapshot.Value.Item1.CurrentState.TryGetValue(ProjectDebugger.SchemaName, out IProjectRuleSnapshot ruleSnapshot))
     {
         ruleSnapshot.Properties.TryGetValue(ProjectDebugger.ActiveDebugProfileProperty, out string activeProfile);
         ILaunchSettings snapshot = CurrentSnapshot;
         if (snapshot == null || !LaunchProfile.IsSameProfileName(activeProfile, snapshot.ActiveProfile?.Name))
         {
             // Updates need to be sequenced
             await _sequentialTaskQueue.ExecuteTask(async() =>
             {
                 using (ProjectCapabilitiesContext.CreateIsolatedContext(_commonProjectServices.Project, projectSnapshot.Value.Item2))
                 {
                     await UpdateActiveProfileInSnapshotAsync(activeProfile);
                 }
             });
         }
     }
 }
        internal void OnNamespaceImportChanged(IProjectVersionedValue <IProjectSubscriptionUpdate> e)
        {
            IProjectChangeDescription projectChange = e.Value.ProjectChanges[NamespaceImport.SchemaName];

            if (projectChange.Difference.AnyChanges)
            {
                lock (_lock)
                {
                    IOrderedEnumerable <string> sortedItems = projectChange.After.Items.Keys.OrderBy(s => s, StringComparer.OrdinalIgnoreCase);
                    int newListCount = sortedItems.Count();
                    int oldListCount = _list.Count;

                    int trackingIndex = 0;

                    while (trackingIndex < oldListCount && trackingIndex < newListCount)
                    {
                        string incomingItem = sortedItems.ElementAt(trackingIndex);
                        if (string.Compare(_list[trackingIndex], incomingItem, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            trackingIndex++;
                            continue;
                        }

                        _list[trackingIndex] = incomingItem;
                        trackingIndex++;
                    }

                    if (oldListCount == newListCount)
                    {
                        return;
                    }
                    else if (oldListCount < newListCount)
                    {
                        _list.AddRange(sortedItems.Skip(trackingIndex));
                    }
                    else
                    {
                        _list.RemoveRange(trackingIndex, oldListCount - trackingIndex);
                    }
                }
            }
        }
        private async Task HandleAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> update, RuleHandlerType handlerType)
        {
            var handlers = Handlers.Select(h => h.Value)
                           .Where(h => h.HandlerType == handlerType);

            // We need to process the update within a lock to ensure that we do not release this context during processing.
            // TODO: Enable concurrent execution of updates themeselves, i.e. two separate invocations of HandleAsync
            //       should be able to run concurrently.
            await ExecuteWithinLockAsync(async() =>
            {
                // TODO: https://github.com/dotnet/roslyn-project-system/issues/353
                await _commonServices.ThreadingService.SwitchToUIThread();

                // Get the inner workspace project context to update for this change.
                var projectContextToUpdate = _currentAggregateProjectContext.GetInnerProjectContext(update.Value.ProjectConfiguration, out bool isActiveContext);
                if (projectContextToUpdate == null)
                {
                    return;
                }

                // Broken design time builds sometimes cause updates with no project changes and sometimes cause updates with a project change that has no difference.
                // We handle the former case here, and the latter case is handled in the CommandLineItemHandler.
                if (update.Value.ProjectChanges.Count == 0)
                {
                    if (handlerType == RuleHandlerType.DesignTimeBuild)
                    {
                        projectContextToUpdate.LastDesignTimeBuildSucceeded = false;
                    }

                    return;
                }

                foreach (var handler in handlers)
                {
                    IProjectChangeDescription projectChange = update.Value.ProjectChanges[handler.RuleName];
                    if (handler.ReceiveUpdatesWithEmptyProjectChange || projectChange.Difference.AnyChanges)
                    {
                        await handler.HandleAsync(update, projectChange, projectContextToUpdate, isActiveContext).ConfigureAwait(true);
                    }
                }
            });
        }
        public void ApplyDesignTime(IProjectVersionedValue <IProjectSubscriptionUpdate> update, bool isActiveContext, CancellationToken cancellationToken)
        {
            Requires.NotNull(update, nameof(update));

            lock (SyncObject)
            {
                VerifyInitializedAndNotDisposed();

                IProjectChangeDescription projectChange = update.Value.ProjectChanges[DesignTimeRuleName];

                if (projectChange.Difference.AnyChanges)
                {
                    IComparable version = GetConfiguredProjectVersion(update);

                    ProcessOptions(projectChange.After);
                    ProcessCommandLine(version, projectChange.Difference, isActiveContext, cancellationToken);
                    ProcessDesignTimeBuildFailure(projectChange.After);
                }
            }
        }
        private async Task HandleAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> update, RuleHandlerType handlerType)
        {
            // We need to process the update within a lock to ensure that we do not release this context during processing.
            // TODO: Enable concurrent execution of updates themeselves, i.e. two separate invocations of HandleAsync
            //       should be able to run concurrently.
            await ExecuteWithinLockAsync(async() =>
            {
                // TODO: https://github.com/dotnet/roslyn-project-system/issues/353
                await _commonServices.ThreadingService.SwitchToUIThread();

                // Get the inner workspace project context to update for this change.
                IWorkspaceProjectContext projectContextToUpdate = _currentAggregateProjectContext.GetInnerProjectContext(update.Value.ProjectConfiguration, out bool isActiveContext);
                if (projectContextToUpdate == null)
                {
                    return;
                }

                _languageServiceHandlerManager.Handle(update, handlerType, projectContextToUpdate, isActiveContext);
            }).ConfigureAwait(false);
        }
Beispiel #26
0
        /// <summary>
        /// Handles changes to the references items in the project and updates the project tree.
        /// </summary>
        /// <param name="e">A description of the changes made to the project.</param>
        private void ProjectSubscriptionService_Changed(IProjectVersionedValue <
                                                            Tuple <IProjectSubscriptionUpdate,
                                                                   IProjectCatalogSnapshot,
                                                                   IProjectSharedFoldersSnapshot> > e)
        {
            var dependenciesChange = ProcessDependenciesChanges(e.Value.Item1, e.Value.Item2);

            // process separatelly shared projects changes
            ProcessSharedProjectImportNodes(e.Value.Item3, dependenciesChange);

            // Apply dependencies changes to actual RootNode children collection
            // remove first nodes from actual RootNode
            dependenciesChange.RemovedNodes.ForEach(RootNode.RemoveChild);

            ProcessDuplicatedNodes(dependenciesChange);

            dependenciesChange.AddedNodes.ForEach(RootNode.AddChild);

            OnDependenciesChanged(dependenciesChange.GetDiff(), e);
        }
Beispiel #27
0
        internal Task OnProjectChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate>?_ = null)
        {
            return(_projectTasksService.LoadedProjectAsync(async() =>
            {
                bool isDebuggable = await _launchProviders.Value.IsDebuggableAsync();

                IVsStartupProjectsListService startupProjectsListService = await _startupProjectsListService.GetValueAsync();

                if (isDebuggable)
                {
                    // If we're already registered, the service no-ops
                    startupProjectsListService.AddProject(ref _projectGuid);
                }
                else
                {
                    // If we're already unregistered, the service no-ops
                    startupProjectsListService.RemoveProject(ref _projectGuid);
                }
            }));
        }
Beispiel #28
0
        private async Task OnProjectChangedAsync(
            IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectSharedFoldersSnapshot, IProjectCatalogSnapshot> > e)
        {
            if (IsDisposing || IsDisposed)
            {
                return;
            }

            EnsureInitialized();


            await _tasksService.LoadedProjectAsync(async() =>
            {
                if (_tasksService.UnloadCancellationToken.IsCancellationRequested)
                {
                    return;
                }

                await HandleAsync(e);
            });
        }
        internal void ProcessDataflowChanges(IProjectVersionedValue <DesignTimeInputsDelta> obj)
        {
            // Cancel any in-progress queue processing
            _compilationCancellationSource?.Cancel();

            DesignTimeInputsDelta delta = obj.Value;

            // add all of the changes to our queue
            _queue.Update(delta.ChangedInputs, delta.Inputs, delta.SharedInputs, delta.TempPEOutputPath);

            // Create a cancellation source so we can cancel the compilation if another message comes through
            _compilationCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(_project.Services.ProjectAsynchronousTasks.UnloadCancellationToken);

            JoinableTask task = _scheduler.ScheduleAsyncTask(ProcessCompileQueueAsync, _compilationCancellationSource.Token);

            // For unit testing purposes, optionally block the thread until the task we scheduled is complete
            if (CompileSynchronously)
            {
                _threadingService.ExecuteSynchronously(() => task.Task);
            }
        }
Beispiel #30
0
        private void ProcessProjectEvaluationHandlers(IComparable version, IProjectVersionedValue <IProjectSubscriptionUpdate> update, bool isActiveContext, CancellationToken cancellationToken)
        {
            foreach (ExportLifetimeContext <IWorkspaceContextHandler> handler in _handlers)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                if (handler.Value is IProjectEvaluationHandler evaluationHandler)
                {
                    IProjectChangeDescription projectChange = update.Value.ProjectChanges[evaluationHandler.ProjectEvaluationRule];
                    if (!projectChange.Difference.AnyChanges)
                    {
                        continue;
                    }

                    evaluationHandler.Handle(version, projectChange, isActiveContext, _logger);
                }
            }
        }