public void VsShellUtils_GetOrCreateSonarLintOutputPane() { // Setup var outputWindow = new ConfigurableVsOutputWindow(); var serviceProvider = new ConfigurableServiceProvider(); serviceProvider.RegisterService(typeof(SVsOutputWindow), outputWindow); // Act IVsOutputWindowPane pane = VsShellUtils.GetOrCreateSonarLintOutputPane(serviceProvider); // Verify outputWindow.AssertPaneExists(VsShellUtils.SonarLintOutputPaneGuid); Assert.IsNotNull(pane); var sonarLintPane = pane as ConfigurableVsOutputWindowPane; if (sonarLintPane == null) { Assert.Inconclusive($"Expected returned pane to be of type {nameof(ConfigurableVsOutputWindowPane)}"); } Assert.IsTrue(sonarLintPane.IsActivated, "Expected pane to be activated"); Assert.AreEqual(Strings.SonarLintOutputPaneTitle, sonarLintPane.Name, "Unexpected pane name."); }
private void OnBindingFinished(ProjectInformation projectInformation, bool isFinishedSuccessfully) { this.IsBindingInProgress = false; this.host.VisualStateManager.ClearBoundProject(); if (isFinishedSuccessfully) { this.host.VisualStateManager.SetBoundProject(projectInformation); var conflictsController = this.host.GetService <IRuleSetConflictsController>(); conflictsController.AssertLocalServiceIsNotNull(); if (conflictsController.CheckForConflicts()) { // In some cases we will end up navigating to the solution explorer, this will make sure that // we're back in team explorer to view the conflicts this.ServiceProvider.GetMefService <ITeamExplorerController>()?.ShowSonarQubePage(); } else { VsShellUtils.ActivateSolutionExplorer(this.ServiceProvider); } } else { IUserNotification notifications = this.host.ActiveSection?.UserNotifications; if (notifications != null) { // Create a command with a fixed argument with the help of ContextualCommandViewModel that creates proxy command for the contextual (fixed) instance and the passed in ICommand that expects it ICommand rebindCommand = new ContextualCommandViewModel(projectInformation, new RelayCommand <ProjectInformation>(this.OnBind, this.OnBindStatus)).Command; notifications.ShowNotificationError(Strings.FailedToToBindSolution, NotificationIds.FailedToBindId, rebindCommand); } } }
private bool HasAdditionalFile(ProjectItem projectItem, string additionalFileName, out string conflictingAdditionalFilePath) { if (additionalFileName.Equals(Path.GetFileName(projectItem.FileNames[0]), StringComparison.OrdinalIgnoreCase)) { var itemTypeProperty = VsShellUtils.FindProperty(projectItem.Properties, Constants.ItemTypePropertyKey); var isMarkedAsAdditionalFile = Constants.AdditionalFilesItemTypeName.Equals(itemTypeProperty.Value?.ToString(), StringComparison.OrdinalIgnoreCase); if (isMarkedAsAdditionalFile) { var pathProperty = VsShellUtils.FindProperty(projectItem.Properties, Constants.FullPathPropertyKey); conflictingAdditionalFilePath = pathProperty.Value.ToString(); return(true); } } foreach (ProjectItem subItem in projectItem.ProjectItems) { if (HasAdditionalFile(subItem, additionalFileName, out conflictingAdditionalFilePath)) { return(true); } } conflictingAdditionalFilePath = string.Empty; return(false); }
public void VsShellUtils_GetOrCreateSonarLintOutputPane() { // Arrange var outputWindow = new ConfigurableVsOutputWindow(); var serviceProvider = new ConfigurableServiceProvider(); serviceProvider.RegisterService(typeof(SVsOutputWindow), outputWindow); // Act IVsOutputWindowPane pane = VsShellUtils.GetOrCreateSonarLintOutputPane(serviceProvider); // Assert outputWindow.AssertPaneExists(VsShellUtils.SonarLintOutputPaneGuid); pane.Should().NotBeNull(); var sonarLintPane = pane as ConfigurableVsOutputWindowPane; if (sonarLintPane == null) { FluentAssertions.Execution.Execute.Assertion.FailWith($"Expected returned pane to be of type {nameof(ConfigurableVsOutputWindowPane)}"); } sonarLintPane.IsActivated.Should().BeTrue("Expected pane to be activated"); sonarLintPane.Name.Should().Be(Strings.SonarLintOutputPaneTitle, "Unexpected pane name."); }
private async Task <bool> AreSolutionProjectsAndSonarQubePluginsCompatible(IProgressController controller, IProgressStepExecutionEvents notifications, CancellationToken cancellationToken) { notifications.ProgressChanged(Strings.DetectingSonarQubePlugins); var plugins = await this.host.SonarQubeService.GetAllPluginsAsync(cancellationToken); var csharpOrVbNetProjects = new HashSet <EnvDTE.Project>(this.projectSystem.GetSolutionProjects()); var supportedSonarQubePlugins = MinimumSupportedSonarQubePlugin.All .Where(lang => IsSonarQubePluginSupported(plugins, lang)) .Select(lang => lang.Language); this.host.SupportedPluginLanguages.UnionWith(new HashSet <Language>(supportedSonarQubePlugins)); // If any of the project can be bound then return success if (csharpOrVbNetProjects.Select(Language.ForProject) .Any(this.host.SupportedPluginLanguages.Contains)) { return(true); } string errorMessage = GetPluginProjectMismatchErrorMessage(csharpOrVbNetProjects); this.host.ActiveSection?.UserNotifications?.ShowNotificationError(errorMessage, NotificationIds.BadSonarQubePluginId, null); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, errorMessage); notifications.ProgressChanged(Strings.ConnectionResultFailure); AbortWorkflow(controller, cancellationToken); return(false); }
// ------------------------------------------------------------------- /// <summary> /// Populates the tree with the current solution and the projects /// loaded in the solution. /// </summary> private void PopulateTree() { string solutionDir, solutionFile, solutionUser; IVsSolution solution = VsShellUtils.GetSolution(serviceProvider); solution.GetSolutionInfo(out solutionDir, out solutionFile, out solutionUser); string solutionName = Path.GetFileNameWithoutExtension(solutionFile); TreeNode root = new TreeNode( String.Format(Messages.SolutionPlaceholder, solutionName)); root.Tag = solution; treeView.Nodes.Add(root); if (FindSolutionInSelection(solution)) { root.Checked = true; } foreach (HierarchyItem item in VsShellUtils.GetLoadedProjects(solution)) { AddHierarchyItemToNode(item, root); } treeView.ExpandAll(); }
private void FindOptionService() { const string optionServiceTypeName = "Microsoft.CodeAnalysis.Options.IOptionService"; const string CodeAnalysisWorkspacesAssemblyName = "Microsoft.CodeAnalysis.Workspaces"; Type optionServiceType = typeof(PerLanguageOption <int>).Assembly.GetType(optionServiceTypeName, false); if (optionServiceType == null) { VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, Strings.MissingResourceAtLocation, optionServiceTypeName, CodeAnalysisWorkspacesAssemblyName); Debug.Fail($"{optionServiceTypeName} could not be found in {CodeAnalysisWorkspacesAssemblyName}"); return; } this.optionService = this.workspace.Services.GetType() ?.GetMethod("GetService") ?.MakeGenericMethod(optionServiceType) ?.Invoke(workspace.Services, null); Debug.Assert(this.optionService != null, "Option service is null"); this.optionServiceSetOptionsMethod = optionServiceType?.GetMethod("SetOptions"); this.optionServiceGetOptionsMethod = optionServiceType?.GetMethod("GetOptions"); Debug.Assert(this.optionServiceSetOptionsMethod != null, "IOptionService.SetOptions method is not found"); Debug.Assert(this.optionServiceGetOptionsMethod != null, "IOptionService.GetOptions method is not found"); }
public void RequestAnalysis(string path, string charset, IList <IContentType> contentTypes) { IssueTagger tracker; if (taggers.TryGetValue(path, out tracker)) { foreach (IContentType type in contentTypes) { if (type.IsOfType("JavaScript")) { daemon.RequestAnalysis(path, charset, "js", null, this); return; } if (type.IsOfType("C/C++")) { string sqLanguage; string json = CFamily.TryGetConfig(tracker.ProjectItem, path, out sqLanguage); if (json != null && sqLanguage != null) { daemon.RequestAnalysis(path, charset, sqLanguage, json, this); } return; } } VsShellUtils.WriteToSonarLintOutputPane(ServiceProvider.GlobalProvider, "Unsupported content type for " + path); } }
private async Task <T> SafeServiceCall <T>(Func <Task <T> > call) { try { return(await call()); } catch (HttpRequestException e) { // For some errors we will get an inner exception which will have a more specific information // that we would like to show i.e.when the host could not be resolved var innerException = e.InnerException as System.Net.WebException; VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SonarQubeRequestFailed, e.Message, innerException?.Message); } catch (TaskCanceledException) { // Canceled or timeout VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SonarQubeRequestTimeoutOrCancelled); } catch (Exception ex) { VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SonarQubeRequestFailed, ex.Message, null); } return(default(T)); }
public void EnumerateProjectProperties_WithConfiguration_MultipleMatches() { // Arrange var project = new ProjectMock("projectfile.proj"); project.Properties.RegisterKnownProperty("no match1").Value = "value1"; project.Properties.RegisterKnownProperty("no match2").Value = "value2"; // Expected results CreatePropertyForConfiguration(project, "config1", "prop1", "config1 prop1"); CreatePropertyForConfiguration(project, "config2", "prop1", "config2 prop1"); CreatePropertyForConfiguration(project, "config4", "prop1", "config4 prop1"); // Additional non-matching properties CreatePropertyForConfiguration(project, "config1", "prop2", "config1 prop2"); CreatePropertyForConfiguration(project, "config2", "propXXX", "config2 propXXX"); CreatePropertyForConfiguration(project, "config3", "prop1aa", "config3 prop1aa"); // Act var result = VsShellUtils.GetProjectProperties(project, "prop1"); // Assert result.Should().NotBeNull(); result.Count().Should().Be(3); result.Select(p => p.Value).Should().BeEquivalentTo( new string[] { "config1 prop1", "config2 prop1", "config4 prop1" }); }
/// <summary> /// Will install the NuGet packages for the current managed projects. /// The packages that will be installed will be based on the information from <see cref="Analyzer.GetRequiredNuGetPackages"/> /// and is specific to the <see cref="RuleSet"/>. /// </summary> internal /*for testing purposes*/ void InstallPackages(IProgressController controller, CancellationToken token, IProgressStepExecutionEvents notificationEvents) { if (!this.NuGetPackages.Any()) { return; } Debug.Assert(this.NuGetPackages.Count == this.NuGetPackages.Distinct().Count(), "Duplicate NuGet packages specified"); if (!this.BindingProjects.Any()) { Debug.Fail("Not expected to be called when there are no projects"); return; } var projectNugets = this.BindingProjects .SelectMany(bindingProject => { var projectLanguage = Language.ForProject(bindingProject); List <NuGetPackageInfoResponse> nugetPackages; if (!this.NuGetPackages.TryGetValue(projectLanguage, out nugetPackages)) { var message = string.Format(Strings.BindingProjectLanguageNotMatchingAnyQualityProfileLanguage, bindingProject.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); nugetPackages = new List <NuGetPackageInfoResponse>(); } return(nugetPackages.Select(nugetPackage => new { Project = bindingProject, NugetPackage = nugetPackage })); }) .ToArray(); DeterminateStepProgressNotifier progressNotifier = new DeterminateStepProgressNotifier(notificationEvents, projectNugets.Length); foreach (var projectNuget in projectNugets) { if (token.IsCancellationRequested) { break; } string message = string.Format(CultureInfo.CurrentCulture, Strings.EnsuringNugetPackagesProgressMessage, projectNuget.NugetPackage.Id, projectNuget.Project.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); var isNugetInstallSuccessful = NuGetHelper.TryInstallPackage(this.host, projectNuget.Project, projectNuget.NugetPackage.Id, projectNuget.NugetPackage.Version); if (isNugetInstallSuccessful) // NuGetHelper.TryInstallPackage already displayed the error message so only take care of the success message { message = string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullyInstalledNugetPackageForProject, projectNuget.NugetPackage.Id, projectNuget.Project.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); } // TODO: SVS-33 (https://jira.sonarsource.com/browse/SVS-33) Trigger a Team Explorer warning notification to investigate the partial binding in the output window. this.AllNuGetPackagesInstalled &= isNugetInstallSuccessful; progressNotifier.NotifyIncrementedProgress(string.Empty); } }
private bool OnBindStatus(ProjectInformation projectInformation) { return(projectInformation != null && this.host.VisualStateManager.IsConnected && !this.host.VisualStateManager.IsBusy && VsShellUtils.IsSolutionExistsAndFullyLoaded() && VsShellUtils.IsSolutionExistsAndNotBuildingAndNotDebugging() && (this.projectSystemHelper.GetSolutionProjects()?.Any() ?? false)); }
private void OnStepExecutionChanged(object sender, StepExecutionChangedEventArgs e) { if (!string.IsNullOrWhiteSpace(e.ProgressDetailText) && !StringComparer.CurrentCulture.Equals(previousProgressDetail, e.ProgressDetailText)) { previousProgressDetail = e.ProgressDetailText; string format = string.IsNullOrWhiteSpace(this.MessageFormat) ? "{0}" : this.MessageFormat; VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, format, e.ProgressDetailText); } }
internal /*for testing purposes*/ void PromptSaveSolutionIfDirty(IProgressController controller, CancellationToken token) { if (!VsShellUtils.SaveSolution(this.host, silent: false)) { VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SolutionSaveCancelledBindAborted); this.AbortWorkflow(controller, token); } }
public bool PromptSaveSolutionIfDirty() { var result = VsShellUtils.SaveSolution(this.host, silent: false); if (!result) { this.host.Logger.WriteLine(Strings.SolutionSaveCancelledBindAborted); } return(result); }
private bool OnBindStatus(BindCommandArgs args) { return(args != null && args.ProjectKey != null && this.host.VisualStateManager.IsConnected && !this.host.VisualStateManager.IsBusy && VsShellUtils.IsSolutionExistsAndFullyLoaded() && VsShellUtils.IsSolutionExistsAndNotBuildingAndNotDebugging() && (this.projectSystemHelper.GetSolutionProjects()?.Any() ?? false)); }
private bool IsSonarQubePluginSupported(IEnumerable <SonarQubePlugin> plugins, MinimumSupportedSonarQubePlugin minimumSupportedPlugin) { var plugin = plugins.FirstOrDefault(x => StringComparer.Ordinal.Equals(x.Key, minimumSupportedPlugin.Key)); var isPluginSupported = !string.IsNullOrWhiteSpace(plugin?.Version) && VersionHelper.Compare(plugin.Version, minimumSupportedPlugin.MinimumVersion) >= 0; var pluginSupportMessageFormat = string.Format(Strings.SubTextPaddingFormat, isPluginSupported ? Strings.SupportedPluginFoundMessage : Strings.UnsupportedPluginFoundMessage); VsShellUtils.WriteToSonarLintOutputPane(this.host, pluginSupportMessageFormat, minimumSupportedPlugin.ToString()); return(isPluginSupported); }
//~ Methods .......................................................... // ------------------------------------------------------ /// <summary> /// Called when the form is loaded. /// </summary> /// <param name="e"> /// An <code>EventArgs</code> object. /// </param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); // Recursively add each project's hierarchy items to the tree. foreach (HierarchyItem item in VsShellUtils.GetLoadedProjects(serviceProvider)) { AddNode(item, hierarchyItemTree.Nodes); } }
private void WriteConflictsSummaryToOutputWindow(IReadOnlyList <ProjectRuleSetConflict> conflicts) { StringBuilder builder = new StringBuilder(); builder.AppendLine(); foreach (ProjectRuleSetConflict conflictInfo in conflicts) { WriteSummaryInformation(conflictInfo, builder); } VsShellUtils.WriteToSonarLintOutputPane(this.host, builder.ToString()); }
private bool VerifyDotNetPlugins(IProgressController controller, CancellationToken cancellationToken, ConnectionInformation connection, IProgressStepExecutionEvents notifications) { notifications.ProgressChanged(Strings.DetectingServerPlugins); ServerPlugin[] plugins; if (!this.host.SonarQubeService.TryGetPlugins(connection, cancellationToken, out plugins)) { notifications.ProgressChanged(cancellationToken.IsCancellationRequested ? Strings.ConnectionResultCancellation : Strings.ConnectionResultFailure); this.host.ActiveSection?.UserNotifications?.ShowNotificationError(Strings.ConnectionFailed, NotificationIds.FailedToConnectId, this.parentCommand); AbortWorkflow(controller, cancellationToken); return(false); } IsCSharpPluginSupported = VerifyPluginSupport(plugins, MinimumSupportedServerPlugin.CSharp); IsVBNetPluginSupported = VerifyPluginSupport(plugins, MinimumSupportedServerPlugin.VbNet); var projects = this.projectSystem.GetSolutionProjects().ToList(); var anyCSharpProject = projects.Any(p => MinimumSupportedServerPlugin.CSharp.ISupported(p)); var anyVbNetProject = projects.Any(p => MinimumSupportedServerPlugin.VbNet.ISupported(p)); string errorMessage; if ((IsCSharpPluginSupported && anyCSharpProject) || (IsVBNetPluginSupported && anyVbNetProject)) { return(true); } else if (!IsCSharpPluginSupported && !IsVBNetPluginSupported) { errorMessage = Strings.ServerHasNoSupportedPluginVersion; } else if (projects.Count == 0) { errorMessage = Strings.SolutionContainsNoSupportedProject; } else if (IsCSharpPluginSupported && !anyCSharpProject) { errorMessage = string.Format(Strings.OnlySupportedPluginHasNoProjectInSolution, Language.CSharp.Name); } else { errorMessage = string.Format(Strings.OnlySupportedPluginHasNoProjectInSolution, Language.VBNET.Name); } this.host.ActiveSection?.UserNotifications?.ShowNotificationError(errorMessage, NotificationIds.BadServerPluginId, null); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, errorMessage); notifications.ProgressChanged(Strings.ConnectionResultFailure); AbortWorkflow(controller, cancellationToken); return(false); }
public static string TryGetConfig(EnvDTE.ProjectItem projectItem, string absoluteFilePath, out string sqLanguage) { try { return(FileConfig.TryGet(projectItem, absoluteFilePath).ToJson(absoluteFilePath, out sqLanguage)); } catch (Exception e) { VsShellUtils.WriteToSonarLintOutputPane(ServiceProvider.GlobalProvider, "Unable to collect C/C++ configuration: " + e.ToString()); sqLanguage = null; return(null); } }
// ------------------------------------------------------ /// <summary> /// Called to update the status of the "Generate New Suite" command /// before it is displayed. /// </summary> /// <param name="sender"> /// The sender of the event. /// </param> /// <param name="e"> /// An <code>EventArgs</code> object. /// </param> private void GenerateTests_BeforeQueryStatus(object sender, EventArgs e) { OleMenuCommand command = (OleMenuCommand)sender; HierarchyItem[] selection = VsShellUtils.GetCurrentSelection(this); // Don't support test generation if more than one file is // selected. if (selection.Length > 1) { command.Supported = false; return; } ProjectItem item = selection[0].GetExtObjectAs <ProjectItem>(); if (item == null) { command.Supported = false; return; } VCFileCodeModel codeModel = (VCFileCodeModel)item.FileCodeModel; // Don't support test generation if the file contains unit tests // already. if (codeModel == null) { command.Supported = false; return; } else { foreach (VCCodeClass klass in codeModel.Classes) { if (klass.Bases.Count > 0 && Constants.CxxTestSuiteClassRegex.IsMatch( klass.Bases.Item(1).Name)) { command.Supported = false; return; } } } command.Supported = true; }
// ------------------------------------------------------------------- /// <summary> /// Collects the current solution loaded into Visual Studio and invokes /// the submission wizard. /// </summary> private void SubmitSolution_Invoked(object sender, EventArgs e) { IVsSolution solution = VsShellUtils.GetSolution(this); if (solution != null) { ISubmittableItem[] items = { new SubmittableSolution(solution) }; ShowSubmissionWizard(items); } }
public bool IsReferenced(Project project, string additionalFilePath) { var fileItem = projectSystemHelper.FindFileInProject(project, additionalFilePath); if (fileItem == null) { return(false); } var property = VsShellUtils.FindProperty(fileItem.Properties, Constants.ItemTypePropertyKey); var isMarkedAsAdditionalFile = Constants.AdditionalFilesItemTypeName.Equals(property.Value?.ToString(), StringComparison.OrdinalIgnoreCase); return(isMarkedAsAdditionalFile); }
public void EnumerateProjectProperties_NullConfigManager_ReturnsNull() { // Arrange var project = new ProjectMock("projectfile.proj"); project.ConfigurationManager = null; // Act var result = VsShellUtils.GetProjectProperties(project, "anyproperty"); // Assert result.Should().NotBeNull(); result.Count().Should().Be(0); }
void IProjectSystemHelper.AddFileToProject(Project project, string file, string itemType) { bool addFileToProject = !project.ProjectItems.OfType <ProjectItem>().Any(pi => StringComparer.OrdinalIgnoreCase.Equals(pi.Name, file)); if (addFileToProject) { var item = project.ProjectItems.AddFromFile(file); Property itemTypeProperty = VsShellUtils.FindProperty(item.Properties, Constants.ItemTypePropertyKey); if (itemTypeProperty != null) { itemTypeProperty.Value = itemType; } } }
// ------------------------------------------------------ /// <summary> /// Creates the test runner source file for the current startup /// project and adds it to the project. /// </summary> /// <param name="doNotRunTests"> /// If true, the file will be generated but will not include any /// statements to run any tests. If false, the tests will be run /// based on the current selection in the CxxTest Suites view. /// </param> public void CreateTestRunnerFile(bool doNotRunTests) { TestSuiteCollection suites = AllTestSuites; Dictionary <string, bool> testsToRun; if (doNotRunTests) { testsToRun = null; } else { testsToRun = TryToGetTestsToRun(); } HierarchyItem startupProject = VsShellUtils.GetStartupProject(this); string projectDir = startupProject.ProjectDirectory; string workingDir = GetActiveWorkingDirectory(startupProject); Project project = startupProject.GetExtObjectAs <Project>(); string runnerPath = Path.Combine( projectDir, Constants.TestRunnerFilename); // Remove the file from the project if necessary, and delete it // from the file system if it exists. VCProject vcproj = (VCProject)project.Object; if (!vcproj.CanAddFile(runnerPath)) { IVCCollection coll = (IVCCollection)vcproj.Files; vcproj.RemoveFile(coll.Item(Constants.TestRunnerFilename)); } if (File.Exists(runnerPath)) { File.Delete(runnerPath); } TestRunnerGenerator generator = new TestRunnerGenerator(runnerPath, suites, testsToRun); generator.Generate(); // Add the file to the project. vcproj.AddFile(runnerPath); }
public void PopulateFromSolution() { TestSuiteCollector collector = new TestSuiteCollector(); foreach (HierarchyItem projectHier in VsShellUtils.GetLoadedProjects(solution)) { Project project = projectHier.GetExtObjectAs <Project>(); collector.Process(project); } suites = collector.Suites; possibleTestFiles = collector.PossibleTestFiles; mainExists = collector.MainFunctionExists; }
private static Option <bool> GetFullSolutionAnalysisOption(IServiceProvider serviceProvider) { if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } string codeAnalysisDllPath = typeof(Accessibility).Assembly.Location; if (string.IsNullOrEmpty(codeAnalysisDllPath)) { Debug.Fail("Microsoft.CodeAnalysis.dll could not be located"); return(null); } FileInfo codeAnalysisAssembly = new FileInfo(codeAnalysisDllPath); if (!codeAnalysisAssembly.Exists) { Debug.Fail("Microsoft.CodeAnalysis.dll could not be located"); return(null); } string codeAnalysisFolderPath = codeAnalysisAssembly.Directory.FullName; const string codeAnalysisFeaturesDllName = "Microsoft.CodeAnalysis.Features.dll"; // There's no public type in the DLL, so we try finding it next to Microsoft.CodeAnalysis string path = Path.Combine(codeAnalysisFolderPath, codeAnalysisFeaturesDllName); if (!File.Exists(path)) { VsShellUtils.WriteToSonarLintOutputPane(serviceProvider, Strings.MissingResourceAtLocation, codeAnalysisFeaturesDllName, codeAnalysisFolderPath); return(null); } // This is only part of Visual Studio 2015 Update 2 Option <bool> option = (Option <bool>)Assembly.LoadFile(path) .GetType("Microsoft.CodeAnalysis.Shared.Options.RuntimeOptions", false) ?.GetField("FullSolutionAnalysis") ?.GetValue(null); Debug.Assert(option != null, "RuntimeOptions is not found"); Debug.Assert(option.Name == OptionNameFullSolutionAnalysis, OptionNameFullSolutionAnalysis + " option name changed to " + option.Name); Debug.Assert(option.Feature == OptionFeatureRuntime, OptionFeatureRuntime + " option feature changed to " + option.Feature); return(option); }
public static IProgressEvents StartAsync(IServiceProvider sp, IProgressControlHost host, Func <IProgressController, ProgressStepDefinition[]> stepFactory) { if (sp == null) { throw new ArgumentNullException(nameof(sp)); } if (host == null) { throw new ArgumentNullException(nameof(host)); } if (stepFactory == null) { throw new ArgumentNullException(nameof(stepFactory)); } Debug.Assert(ThreadHelper.CheckAccess(), "Expected to be called on the UI thread"); // Initialize a controller and an observer var controller = new SequentialProgressController(sp); controller.Initialize(stepFactory(controller)); IVsOutputWindowPane sonarLintPane = VsShellUtils.GetOrCreateSonarLintOutputPane(sp); bool logFullMessage; #if DEBUG logFullMessage = true; #else logFullMessage = false; #endif var notifier = new VsOutputWindowPaneNotifier(sp, sonarLintPane, ensureOutputVisible: true, messageFormat: Strings.UnexpectedWorkflowError, logFullException: logFullMessage); controller.ErrorNotificationManager.AddNotifier(notifier); Observe(controller, host); controller.RunOnFinished(r => observedControllersMap.Remove(controller)); #pragma warning disable 4014 // We do want to start and forget. All the errors will be forwarded via the error notification manager controller.StartAsync(); #pragma warning restore 4014 return(controller); }