Пример #1
0
        public void AddProject(AbstractProject project)
        {
            var creationInfo = new VisualStudioProjectCreationInfo
            {
                AssemblyName = project.AssemblyName,
                FilePath     = project.ProjectFilePath,
                Hierarchy    = project.Hierarchy,
                ProjectGuid  = project.Guid,
            };

            project.VisualStudioProject = _projectFactory.CreateAndAddToWorkspace(project.ProjectSystemName, project.Language, creationInfo);
            project.UpdateVisualStudioProjectProperties();

            _typeScriptProjects[project.Id] = project;
        }
        public void AddProject(AbstractProject project)
        {
            if (_projectFactory != null)
            {
                var creationInfo = new VisualStudioProjectCreationInfo
                {
                    AssemblyName = project.AssemblyName,
                    FilePath     = project.ProjectFilePath,
                    ProjectGuid  = project.Guid,
                };
                project.VisualStudioProject = _projectFactory.CreateAndAddToWorkspace(project.ProjectSystemName, project.Language, creationInfo);
                project.UpdateVisualStudioProjectProperties();
            }
            else
            {
                // We don't have an ID, so make something up
                project.ExplicitId = ProjectId.CreateNewId(project.ProjectSystemName);
                Workspace.OnProjectAdded(ProjectInfo.Create(project.ExplicitId, VersionStamp.Create(), project.ProjectSystemName, project.ProjectSystemName, project.Language));
            }

            _projects[project.Id] = project;
        }
Пример #3
0
        public VisualStudioProject CreateAndAddToWorkspace(string projectUniqueName, string language, VisualStudioProjectCreationInfo creationInfo)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            var id = ProjectId.CreateNewId(projectUniqueName);
            var directoryNameOpt = creationInfo.FilePath != null?Path.GetDirectoryName(creationInfo.FilePath) : null;

            var project = new VisualStudioProject(_visualStudioWorkspaceImpl, _dynamicFileInfoProviders, _hostDiagnosticUpdateSource, id, projectUniqueName, language, directoryNameOpt);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            var assemblyName = creationInfo.AssemblyName ?? projectUniqueName;

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectUniqueName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectUniqueName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions);

                // HACK: update this since we're still on the UI thread. Note we can only update this if we don't have projects -- the workspace
                // only lets us really do this with OnSolutionAdded for now.
                string solutionPathToSetWithOnSolutionAdded = null;
                var solution = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution));
                if (solution != null && ErrorHandler.Succeeded(solution.GetSolutionInfo(out _, out var solutionFilePath, out _)))
                {
                    if (w.CurrentSolution.FilePath != solutionFilePath && w.CurrentSolution.ProjectIds.Count == 0)
                    {
                        solutionPathToSetWithOnSolutionAdded = solutionFilePath;
                    }
                }

                if (solutionPathToSetWithOnSolutionAdded != null)
                {
                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionPathToSetWithOnSolutionAdded),
                            VersionStamp.Create(),
                            solutionPathToSetWithOnSolutionAdded,
                            projects: new[] { projectInfo }));

                    // set working folder for the persistent service
                    var persistenceService = w.Services.GetRequiredService <IPersistentStorageLocationService>() as VisualStudioPersistentStorageLocationService;
                    persistenceService?.UpdateForVisualStudioWorkspace(w);
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }
            });

            // We do all these sets after the w.OnProjectAdded, as the setting of these properties is going to try to modify the workspace
            // again. Those modifications will all implicitly do nothing, since the workspace already has the values from above.
            // We could pass these all through the constructor (but that gets verbose), or have some other control to ignore these,
            // but that seems like overkill.
            project.AssemblyName       = assemblyName;
            project.CompilationOptions = creationInfo.CompilationOptions;
            project.FilePath           = creationInfo.FilePath;
            project.ParseOptions       = creationInfo.ParseOptions;

            return(project);
        }
Пример #4
0
        public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            // HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service
            _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized();

            var id = ProjectId.CreateNewId(projectSystemName);
            var directoryNameOpt = creationInfo.FilePath != null?Path.GetDirectoryName(creationInfo.FilePath) : null;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(_visualStudioWorkspaceImpl, _dynamicFileInfoProviders, _hostDiagnosticUpdateSource, id, displayName: projectSystemName, language, directoryNameOpt);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    // Fetch the current solution path. Since we're on the UI thread right now, we can do that.
                    string solutionFilePath = null;
                    var solution            = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution));
                    if (solution != null)
                    {
                        if (ErrorHandler.Failed(solution.GetSolutionInfo(out _, out solutionFilePath, out _)))
                        {
                            // Paranoia: if the call failed, we definitely don't want to use any stuff that was set
                            solutionFilePath = null;
                        }
                    }

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo }));

                    // set working folder for the persistent service
                    var persistenceService = w.Services.GetRequiredService <IPersistentStorageLocationService>() as VisualStudioPersistentStorageLocationService;
                    persistenceService?.UpdateForVisualStudioWorkspace(w);
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }
            });

            // We do all these sets after the w.OnProjectAdded, as the setting of these properties is going to try to modify the workspace
            // again. Those modifications will all implicitly do nothing, since the workspace already has the values from above.
            // We could pass these all through the constructor (but that gets verbose), or have some other control to ignore these,
            // but that seems like overkill.
            project.AssemblyName       = assemblyName;
            project.CompilationOptions = creationInfo.CompilationOptions;
            project.FilePath           = creationInfo.FilePath;
            project.ParseOptions       = creationInfo.ParseOptions;

            return(project);
        }
        public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            // HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service
            _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized();

            var id           = ProjectId.CreateNewId(projectSystemName);
            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(
                _visualStudioWorkspaceImpl,
                _dynamicFileInfoProviders,
                _hostDiagnosticUpdateSource,
                id,
                displayName: projectSystemName,
                language,
                assemblyName: assemblyName,
                compilationOptions: creationInfo.CompilationOptions,
                filePath: creationInfo.FilePath,
                parseOptions: creationInfo.ParseOptions);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            _visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

            _visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
            {
                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions)
                                  .WithTelemetryId(creationInfo.ProjectGuid);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    // Fetch the current solution path. Since we're on the UI thread right now, we can do that.
                    string?solutionFilePath = null;
                    var solution            = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution));
                    if (solution != null)
                    {
                        if (ErrorHandler.Failed(solution.GetSolutionInfo(out _, out solutionFilePath, out _)))
                        {
                            // Paranoia: if the call failed, we definitely don't want to use any stuff that was set
                            solutionFilePath = null;
                        }
                    }

                    var solutionSessionId = GetSolutionSessionId();

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo },
                            analyzerReferences: w.CurrentSolution.AnalyzerReferences)
                        .WithTelemetryId(solutionSessionId));
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }

                _visualStudioWorkspaceImpl.RefreshProjectExistsUIContextForLanguage(language);
            });

            return(project);
Пример #6
0
        public async Task <VisualStudioProject> CreateAndAddToWorkspaceAsync(
            string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo, CancellationToken cancellationToken)
        {
            // HACK: Fetch this service to ensure it's still created on the UI thread; once this is
            // moved off we'll need to fix up it's constructor to be free-threaded.

            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            _visualStudioWorkspaceImpl.Services.GetRequiredService <VisualStudioMetadataReferenceManager>();

            _visualStudioWorkspaceImpl.SubscribeExternalErrorDiagnosticUpdateSourceToSolutionBuildEvents();

            // Since we're on the UI thread here anyways, use that as an opportunity to grab the
            // IVsSolution object and solution file path.
            //
            // ConfigureAwait(true) as we have to come back to the UI thread to do the cast to IVsSolution2.
            var solution = (IVsSolution2?)await _serviceProvider.GetServiceAsync(typeof(SVsSolution)).ConfigureAwait(true);

            var solutionFilePath = solution != null && ErrorHandler.Succeeded(solution.GetSolutionInfo(out _, out var filePath, out _))
                ? filePath
                : null;

            // Following can be off the UI thread.
            await TaskScheduler.Default;

            // From this point on, we start mutating the solution.  So make us non cancellable.
            cancellationToken = CancellationToken.None;

            var id           = ProjectId.CreateNewId(projectSystemName);
            var assemblyName = creationInfo.AssemblyName ?? projectSystemName;

            // We will use the project system name as the default display name of the project
            var project = new VisualStudioProject(
                _visualStudioWorkspaceImpl,
                _dynamicFileInfoProviders,
                _hostDiagnosticUpdateSource,
                id,
                displayName: projectSystemName,
                language,
                assemblyName: assemblyName,
                compilationOptions: creationInfo.CompilationOptions,
                filePath: creationInfo.FilePath,
                parseOptions: creationInfo.ParseOptions);

            var versionStamp = creationInfo.FilePath != null?VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
                                   : VersionStamp.Create();

            await _visualStudioWorkspaceImpl.ApplyChangeToWorkspaceAsync(w =>
            {
                _visualStudioWorkspaceImpl.AddProjectToInternalMaps_NoLock(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

                var projectInfo = ProjectInfo.Create(
                    id,
                    versionStamp,
                    name: projectSystemName,
                    assemblyName: assemblyName,
                    language: language,
                    filePath: creationInfo.FilePath,
                    compilationOptions: creationInfo.CompilationOptions,
                    parseOptions: creationInfo.ParseOptions)
                                  .WithTelemetryId(creationInfo.ProjectGuid);

                // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
                // and count this as the solution being added so that event is raised.
                if (w.CurrentSolution.ProjectIds.Count == 0)
                {
                    var solutionSessionId = GetSolutionSessionId();

                    w.OnSolutionAdded(
                        SolutionInfo.Create(
                            SolutionId.CreateNewId(solutionFilePath),
                            VersionStamp.Create(),
                            solutionFilePath,
                            projects: new[] { projectInfo },
                            analyzerReferences: w.CurrentSolution.AnalyzerReferences)
                        .WithTelemetryId(solutionSessionId));
                }
                else
                {
                    w.OnProjectAdded(projectInfo);
                }
            }).ConfigureAwait(false);

            // Ensure that other VS contexts get accurate information that the UIContext for this language is now active.
            // This is not cancellable as we have already mutated the solution.
            await _visualStudioWorkspaceImpl.RefreshProjectExistsUIContextForLanguageAsync(language, CancellationToken.None).ConfigureAwait(false);

            return(project);