예제 #1
0
        public override Task OnContextReleasedAsync(IWorkspaceProjectContext context)
        {
            Requires.NotNull(context, nameof(context));

            _sourceFilesByContext.Remove(context);
            return(Task.CompletedTask);
        }
        private Handlers CreateHandlers(IWorkspaceProjectContext context)
        {
            var evaluationHandlers = PooledArray <(IProjectEvaluationHandler handler, string evaluationRuleName)> .GetInstance();

            var commandLineHandlers = PooledArray <ICommandLineHandler> .GetInstance();

            foreach ((HandlerFactory factory, string evaluationRuleName)factory in s_handlerFactories)
            {
                IWorkspaceContextHandler handler = factory.factory(_project);
                handler.Initialize(context);

                // NOTE: Handlers can be both IEvaluationHandler and ICommandLineHandler
                if (handler is IProjectEvaluationHandler evaluationHandler)
                {
                    evaluationHandlers.Add((evaluationHandler, factory.evaluationRuleName));
                }

                if (handler is ICommandLineHandler commandLineHandler)
                {
                    commandLineHandlers.Add(commandLineHandler);
                }
            }

            return(new Handlers(evaluationHandlers.ToImmutableAndFree(), commandLineHandlers.ToImmutableAndFree()));
        }
예제 #3
0
        public override void Handle(IProjectChangeDescription projectChange, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Requires.NotNull(projectChange, nameof(projectChange));
            Requires.NotNull(context, nameof(context));

            IProjectChangeDiff diff = projectChange.Difference;

            foreach (string filePath in diff.RemovedItems)
            {
                RemoveSourceFile(filePath, context);
            }

            foreach (string filePath in diff.AddedItems)
            {
                AddSourceFile(filePath, GetFolders(filePath, projectChange), context, isActiveContext);
            }

            foreach (KeyValuePair <string, string> filePaths in diff.RenamedItems)
            {
                string removeFilePath = filePaths.Key;
                string addFilePath    = filePaths.Value;

                RemoveSourceFile(removeFilePath, context);
                AddSourceFile(addFilePath, GetFolders(addFilePath, projectChange), context, isActiveContext);
            }

            foreach (string filePath in diff.ChangedItems)
            {
                // We add and then remove ChangedItems to handle Linked metadata changes
                RemoveSourceFile(filePath, context);
                AddSourceFile(filePath, GetFolders(filePath, projectChange), context, isActiveContext);
            }
        }
예제 #4
0
        public async Task <IWorkspaceProjectContext> CreateProjectContextAsync(ConfiguredProject project)
        {
            Requires.NotNull(project, nameof(project));

            ProjectContextInitData data = await GetProjectContextInitDataAsync(project);

            if (data.IsInvalid())
            {
                return(null);
            }

            object hostObject = _project.Services.HostObject;

            IWorkspaceProjectContext context = await CreateProjectContextHandlingFaultAsync(data, hostObject);

            if (context == null)
            {
                return(null);
            }

            // Wrap to enforce UI-thread
            context = new ForegroundWorkspaceProjectContext(_threadingService, context);

            _activeWorkspaceProjectContextTracker.RegisterContext(context, data.WorkspaceProjectContextId);

            return(context);
        }
        private async Task <IWorkspaceProjectContext?> CreateProjectContextHandlingFaultAsync(ProjectContextInitData data, object?hostObject)
        {
            try
            {
                // Call into Roslyn to init language service for this project
                IWorkspaceProjectContext context = await _workspaceProjectContextFactory.Value.CreateProjectContextAsync(
                    data.LanguageName,
                    data.WorkspaceProjectContextId,
                    data.ProjectFilePath,
                    data.ProjectGuid,
                    hostObject,
                    data.BinOutputPath,
                    data.AssemblyName,
                    CancellationToken.None);

                context.LastDesignTimeBuildSucceeded = false;  // By default, turn off diagnostics until the first design time build succeeds for this project.

                return(context);
            }
            catch (Exception ex)
            {
                await _faultHandlerService.ReportFaultAsync(ex, _project, ProjectFaultSeverity.LimitedFunctionality);
            }

            return(null);
        }
        private async Task <IWorkspaceProjectContext> CreateProjectContextHandlingFaultAsync(ProjectContextInitData data, object hostObject)
        {
            // TODO: https://github.com/dotnet/project-system/issues/353.
            await _threadingService.SwitchToUIThread();

            try
            {
                // Call into Roslyn to init language service for this project
                IWorkspaceProjectContext context = _workspaceProjectContextFactory.Value.CreateProjectContext(
                    data.LanguageName,
                    data.WorkspaceProjectContextId,
                    data.ProjectFilePath,
                    data.ProjectGuid,
                    hostObject,
                    data.BinOutputPath);

                context.LastDesignTimeBuildSucceeded = false;  // By default, turn off diagnostics until the first design time build succeeds for this project.

                return(context);
            }
            catch (Exception ex)
            {
                await _faultHandlerService.ReportFaultAsync(ex, _project, ProjectFaultSeverity.LimitedFunctionality);
            }

            return(null);
        }
예제 #7
0
        private SourceItemHandler CreateInstance(UnconfiguredProject project = null, IWorkspaceProjectContext context = null)
        {
            project = project ?? UnconfiguredProjectFactory.Create();
            context = context ?? IWorkspaceProjectContextFactory.Create();

            return(new SourceItemHandler(project, context));
        }
            private async Task ApplyProjectChangesUnderLockAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> update, bool evaluation, CancellationToken cancellationToken)
            {
                IWorkspaceProjectContext context = _contextAccessor !.Context;

                context.StartBatch();

                try
                {
                    bool isActiveContext = _activeWorkspaceProjectContextTracker.IsActiveEditorContext(_contextAccessor.ContextId);

                    if (evaluation)
                    {
                        await _applyChangesToWorkspaceContext !.Value.ApplyProjectEvaluationAsync(update, isActiveContext, cancellationToken);
                    }
                    else
                    {
                        await _applyChangesToWorkspaceContext !.Value.ApplyProjectBuildAsync(update, isActiveContext, cancellationToken);
                    }
                }
                finally
                {
                    context.EndBatch();

                    NotifyOutputDataCalculated(update.DataSourceVersions, evaluation);
                }

                await _applyChangesToWorkspaceContext.Value.ApplyProjectEndBatchAsync(update, cancellationToken);
            }
        private static void ProcessOptions(IProjectChangeDescription projectChange, IWorkspaceProjectContext context)
        {
            // We don't pass differences to Roslyn for options, we just pass them all
            IEnumerable <string> commandlineArguments = projectChange.After.Items.Keys;

            context.SetOptions(string.Join(" ", commandlineArguments));
        }
예제 #10
0
        public FileCodeModel GetFileCodeModel(ProjectItem fileItem)
        {
            Requires.NotNull(fileItem, nameof(fileItem));

            IWorkspaceProjectContext projectContext = _languageServiceHost.ActiveProjectContext;

            if (projectContext == null)
            {
                return(null);
            }

            return(_threadingService.ExecuteSynchronously(async() =>
            {
                await _threadingService.SwitchToUIThread();

                try
                {
                    return _codeModelFactory.GetFileCodeModel(projectContext, fileItem);
                }
                catch (NotImplementedException)
                {   // Isn't a file that Roslyn knows about
                }

                return null;
            }));
        }
예제 #11
0
        public void RemoveProjectReference(IWorkspaceProjectContext project)
        {
            var referencedProject = GetAbstractProject(project);
            var projectReference  = GetCurrentProjectReferences().Single(p => p.ProjectId == referencedProject.Id);

            RemoveProjectReference(projectReference);
        }
        public override void Handle(IProjectChangeDescription projectChange, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Requires.NotNull(projectChange, nameof(projectChange));

            if (projectChange.Difference.ChangedProperties.Contains(ConfigurationGeneral.ProjectGuidProperty))
            {
                if (Guid.TryParse(projectChange.After.Properties[ConfigurationGeneral.ProjectGuidProperty], out Guid result))
                {
                    context.Guid = result;
                }
            }

            // The language service wants both the intermediate (bin\obj) and output (bin\debug)) paths
            // so that it can automatically hook up project-to-project references. It does this by matching the
            // bin output path with the another project's /reference argument, if they match, then it automatically
            // introduces a project reference between the two. We pass the intermediate path via the /out
            // command-line argument and set via one of the other handlers, where as the latter is calculated via
            // the TargetPath property and explictly set on the context.

            if (projectChange.Difference.ChangedProperties.Contains(ConfigurationGeneral.TargetPathProperty))
            {
                var newBinOutputPath = projectChange.After.Properties[ConfigurationGeneral.TargetPathProperty];
                if (!string.IsNullOrEmpty(newBinOutputPath))
                {
                    context.BinOutputPath = newBinOutputPath;
                }
            }
        }
        public ImmutableArray <ICommandLineHandler> GetCommandLineHandlers(IWorkspaceProjectContext context)
        {
            Requires.NotNull(context, nameof(context));

            Handlers handlers = _contextToHandlers.GetOrAdd(context, CreateHandlers);

            return(handlers.CommandLineHandlers);
        }
예제 #14
0
 public void AddProjectReference(IWorkspaceProjectContext project, MetadataReferenceProperties properties)
 {
     ExecuteForegroundAction(() =>
     {
         var abstractProject = GetAbstractProject(project);
         AddProjectReference(new ProjectReference(abstractProject.Id, properties.Aliases, properties.EmbedInteropTypes));
     });
 }
 private void AddConfiguredProjectState(ConfiguredProject configuredProject, IWorkspaceProjectContext workspaceProjectContext, IConfiguredProjectHostObject configuredProjectHostObject)
 {
     lock (_gate)
     {
         _configuredProjectContextsMap.Add(configuredProject, workspaceProjectContext);
         _configuredProjectHostObjectsMap.Add(configuredProject, configuredProjectHostObject);
     }
 }
예제 #16
0
        public MetadataReferenceItemHandler(UnconfiguredProject project, IWorkspaceProjectContext context)
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNull(context, nameof(context));

            _project = project;
            _context = context;
        }
            public ForegroundWorkspaceProjectContext(IProjectThreadingService threadingService, IWorkspaceProjectContext underlyingContext)
            {
                Assumes.NotNull(threadingService);
                Assumes.NotNull(underlyingContext);

                _threadingService  = threadingService;
                _underlyingContext = underlyingContext;
            }
        private static void ProcessOptions(IProjectChangeDescription projectChange, IWorkspaceProjectContext context, IProjectLogger logger)
        {
            // We don't pass differences to Roslyn for options, we just pass them all
            string commandlineArguments = string.Join(" ", projectChange.After.Items.Keys);

            WriteCommandLineArguments(logger, commandlineArguments);
            context.SetOptions(commandlineArguments);
        }
        public AnalyzerItemHandler(UnconfiguredProject project, IWorkspaceProjectContext context)
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNull(context, nameof(context));

            _project = project;
            _context = context;
        }
        public void Initialize(IWorkspaceProjectContext context)
        {
            Requires.NotNull(context, nameof(context));

            if (_context != null)
                throw new InvalidOperationException();

            _context = context;
        }
예제 #21
0
 public void RemoveProjectReference(IWorkspaceProjectContext project)
 {
     ExecuteForegroundAction(() =>
     {
         var referencedProject = GetAbstractProject(project);
         var projectReference  = GetCurrentProjectReferences().Single(p => p.ProjectId == referencedProject.Id);
         RemoveProjectReference(projectReference);
     });
 }
예제 #22
0
        public void ProjectLastDesignTimeBuildSucceededSetter_CPS()
        {
            using var environment = new TestEnvironment();
            using IWorkspaceProjectContext projectContext = CSharpHelpers.CreateCSharpCPSProject(environment, "Test");
            Assert.True(projectContext.LastDesignTimeBuildSucceeded);

            projectContext.LastDesignTimeBuildSucceeded = false;
            Assert.False(projectContext.LastDesignTimeBuildSucceeded);
        }
예제 #23
0
        private void RemoveSourceFile(string fullPath, IWorkspaceProjectContext context)
        {
            fullPath = _project.MakeRooted(fullPath);

            if (_sourceFilesByContext.TryGetValue(context, out HashSet <string> sourceFiles) && sourceFiles.Remove(fullPath))
            {
                context.RemoveSourceFile(fullPath);
            }
        }
예제 #24
0
        private static ApplyChangesToWorkspaceContext CreateInitializedInstance(out IWorkspaceProjectContext context, ConfiguredProject?project = null, ICommandLineParserService?commandLineParser = null, IProjectLogger?logger = null, params IWorkspaceContextHandler[] handlers)
        {
            var applyChangesToWorkspace = CreateInstance(project, commandLineParser, logger, handlers);

            context = IWorkspaceProjectContextMockFactory.Create();

            applyChangesToWorkspace.Initialize(context);

            return(applyChangesToWorkspace);
        }
        private void ProcessItems(IProjectChangeDescription projectChange, IWorkspaceProjectContext context, bool isActiveContext)
        {
            CommandLineArguments addedItems   = _commandLineParser.Parse(projectChange.Difference.AddedItems);
            CommandLineArguments removedItems = _commandLineParser.Parse(projectChange.Difference.RemovedItems);

            foreach (var handler in Handlers)
            {
                handler.Value.Handle(addedItems, removedItems, context, isActiveContext);
            }
        }
        public override void Handle(IProjectChangeDescription projectChange, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Requires.NotNull(projectChange, nameof(projectChange));

            if (!ProcessDesignTimeBuildFailure(projectChange, context))
            {
                ProcessOptions(projectChange, context);
                ProcessItems(projectChange, context, isActiveContext);
            }
        }
예제 #27
0
            internal Task OnProjectChangedAsync <T>(
                IDataProgressTrackerServiceRegistration registration,
                ConfiguredProject activeConfiguredProject,
                IProjectVersionedValue <T> update,
                Func <IProjectVersionedValue <T>, bool> hasChange,
                Action <IProjectVersionedValue <T>, IApplyChangesToWorkspaceContext, ContextState, CancellationToken> applyFunc)
            {
                return(ExecuteUnderLockAsync(ApplyProjectChangesUnderLockAsync, _tasksService.UnloadCancellationToken));

                Task ApplyProjectChangesUnderLockAsync(CancellationToken cancellationToken)
                {
                    // NOTE we cannot call CheckForInitialized here, as this method may be invoked during initialization
                    Assumes.NotNull(_contextAccessor);
                    Assumes.NotNull(_applyChangesToWorkspaceContext);

                    if (!hasChange(update))
                    {
                        // No change since the last update. We must still update operation progress, but can skip creating a batch.
                        UpdateProgressRegistration();
                        return(Task.CompletedTask);
                    }

                    return(ApplyInBatchAsync());

                    async Task ApplyInBatchAsync()
                    {
                        ContextState contextState = new(
                            isActiveEditorContext : _activeWorkspaceProjectContextTracker.IsActiveEditorContext(_contextAccessor.ContextId),
                            isActiveConfiguration : activeConfiguredProject == _project);

                        IWorkspaceProjectContext context = _contextAccessor.Context;

                        context.StartBatch();

                        try
                        {
                            applyFunc(update, _applyChangesToWorkspaceContext.Value, contextState, cancellationToken);
                        }
                        finally
                        {
                            await context.EndBatchAsync();

                            UpdateProgressRegistration();
                        }
                    }

                    void UpdateProgressRegistration()
                    {
                        // Notify operation progress that we've now processed these versions of our input, if they are
                        // up-to-date with the latest version that produced, then we no longer considered "in progress".
                        registration.NotifyOutputDataCalculated(update.DataSourceVersions);
                    }
                }
            }
        public bool IsActiveContext(IWorkspaceProjectContext context)
        {
            Requires.NotNull(context, nameof(context));

            if (_contexts.TryGetValue(context, out string projectContextId))
            {
                return(StringComparers.WorkspaceProjectContextIds.Equals(ActiveIntellisenseProjectContext, projectContextId));
            }

            throw new InvalidOperationException("'context' has not been registered or has already been unregistered");
        }
예제 #29
0
        public void SetContext(IWorkspaceProjectContext context)
        {
            Requires.NotNull(context, nameof(context));

            _context = context;

            foreach (var handler in Handlers)
            {
                handler.Value.SetContext(_context);
            }
        }
예제 #30
0
        private AbstractProject GetAbstractProject(IWorkspaceProjectContext project)
        {
            var abstractProject = project as AbstractProject;

            if (abstractProject == null)
            {
                throw new ArgumentException("Unsupported project kind", nameof(project));
            }

            return(abstractProject);
        }
        private AbstractProject GetAbstractProject(IWorkspaceProjectContext project)
        {
            var abstractProject = project as AbstractProject;
            if (abstractProject == null)
            {
                throw new ArgumentException("Unsupported project kind", nameof(project));
            }

            return abstractProject;
        }
예제 #32
0
 public EnvDTE.FileCodeModel GetFileCodeModel(IWorkspaceProjectContext context, EnvDTE.ProjectItem item)
 {
     return ((CPSProject)context).GetFileCodeModel(item);
 }
예제 #33
0
 public EnvDTE.CodeModel GetCodeModel(IWorkspaceProjectContext context, EnvDTE.Project project)
 {
     return ((CPSProject)context).GetCodeModel(project);
 }
        public void RemoveProjectReference(IWorkspaceProjectContext project)
        {
            var referencedProject = GetAbstractProject(project);

            // AbstractProject and ProjectTracker track project references using the project bin output path.
            // We fetch this output path to remove the reference.
            var binPathOpt = referencedProject.TryGetBinOutputPath();
            if (!string.IsNullOrEmpty(binPathOpt))
            {
                base.RemoveMetadataReference(binPathOpt);
            }
        }
 public void AddProjectReference(IWorkspaceProjectContext project, MetadataReferenceProperties properties)
 {
     var abstractProject = GetAbstractProject(project);
     AddProjectReference(new ProjectReference(abstractProject.Id, properties.Aliases, properties.EmbedInteropTypes));
 }
        public void AddProjectReference(IWorkspaceProjectContext project, MetadataReferenceProperties properties)
        {
            var abstractProject = GetAbstractProject(project);

            // AbstractProject and ProjectTracker track project references using the project bin output path.
            // Setting the command line arguments should have already set the output file name and folder.
            // We fetch this output path to add the reference.
            var referencedProject = this.ProjectTracker.GetProject(abstractProject.Id);
            var binPathOpt = referencedProject.TryGetBinOutputPath();
            if (!string.IsNullOrEmpty(binPathOpt))
            {
                AddMetadataReferenceAndTryConvertingToProjectReferenceIfPossible(binPathOpt, properties);
            }
        }
 public void RemoveProjectReference(IWorkspaceProjectContext project)
 {
     var referencedProject = GetAbstractProject(project);
     var projectReference = GetCurrentProjectReferences().Single(p => p.ProjectId == referencedProject.Id);
     RemoveProjectReference(projectReference);
 }
 public void RemoveProjectReference(IWorkspaceProjectContext project)
 {
     ExecuteForegroundAction(() =>
     {
         var referencedProject = GetAbstractProject(project);
         var projectReference = GetCurrentProjectReferences().Single(p => p.ProjectId == referencedProject.Id);
         RemoveProjectReference(projectReference);
     });
 }