private void SetSeverityHandler(object sender, EventArgs args) { var selectedItem = (MenuCommand)sender; var reportDiagnostic = TryMapSelectedItemToReportDiagnostic(selectedItem); if (reportDiagnostic == null) { return; } var selectedDiagnostic = TryGetSingleSelectedEntry(); if (selectedDiagnostic == null) { return; } var pathToAnalyzerConfigDoc = TryGetPathToAnalyzerConfigDoc(selectedDiagnostic, out var project); if (pathToAnalyzerConfigDoc != null) { var result = _uiThreadOperationExecutor.Execute( title: ServicesVSResources.Updating_severity, defaultDescription: ServicesVSResources.Updating_severity, allowCancellation: true, showProgress: true, action: context => { var newSolution = ConfigureSeverityAsync(context.UserCancellationToken).WaitAndGetResult(context.UserCancellationToken); var operations = ImmutableArray.Create <CodeActionOperation>(new ApplyChangesOperation(newSolution)); var scope = context.AddScope(allowCancellation: true, ServicesVSResources.Updating_severity); _editHandlerService.Apply( _workspace, fromDocument: null, operations: operations, title: ServicesVSResources.Updating_severity, progressTracker: new UIThreadOperationContextProgressTracker(scope), cancellationToken: context.UserCancellationToken); }); if (result == UIThreadOperationStatus.Completed && selectedDiagnostic.DocumentId != null) { // Kick off diagnostic re-analysis for affected document so that the configured diagnostic gets refreshed. Task.Run(() => { _diagnosticService.Reanalyze(_workspace, documentIds: SpecializedCollections.SingletonEnumerable(selectedDiagnostic.DocumentId), highPriority: true); }); } } return; // Local functions. async System.Threading.Tasks.Task <Solution> ConfigureSeverityAsync(CancellationToken cancellationToken) { var diagnostic = await selectedDiagnostic.ToDiagnosticAsync(project, cancellationToken).ConfigureAwait(false); return(await ConfigurationUpdater.ConfigureSeverityAsync(reportDiagnostic.Value, diagnostic, project, cancellationToken).ConfigureAwait(false)); } }
internal Task <Solution> GetSolutionWithUpdatedAnalyzerConfigSeverityAsync(ReportDiagnostic value, Project project, CancellationToken cancellationToken) { var effectiveSeverity = value.ToDiagnosticSeverity() ?? Descriptor.DefaultSeverity; var diagnostic = Diagnostic.Create(Descriptor, Location.None, effectiveSeverity, additionalLocations: null, properties: null); return(ConfigurationUpdater.ConfigureSeverityAsync(value, diagnostic, project, cancellationToken)); }
public ConfigurationUpdaterTests() { sourcePath = AppDomain.CurrentDomain.BaseDirectory + sourcePath; _readerMoq = new Mock <IReader>(); _writerMoq = new Mock <IWriter>(); _loggerMoq = new Mock <ILogger <ConfigurationUpdater> >(); _target = new ConfigurationUpdater(_loggerMoq.Object, _readerMoq.Object, _writerMoq.Object); }
public ConfigureMenuHandler(ConfigurationUpdater configurationUpdater, NotifyIconManager notifyIconManager) { this.configurationUpdater = configurationUpdater ?? throw new ArgumentNullException(nameof(configurationUpdater)); if (notifyIconManager is null) { throw new ArgumentNullException(nameof(notifyIconManager)); } notifyIconManager.NotifyIcon.DoubleClick += NotifyIcon_DoubleClick; }
public MonitorForm( ILogger <MonitorForm> logger, ShutdownLocker shutdownMonitor, MassController autoController, ConfigurationUpdater configurationUpdater ) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.shutdownMonitor = shutdownMonitor ?? throw new ArgumentNullException(nameof(shutdownMonitor)); this.autoController = autoController ?? throw new ArgumentNullException(nameof(autoController)); this.configurationUpdater = configurationUpdater ?? throw new ArgumentNullException(nameof(configurationUpdater)); InitializeComponent(); }
static void Main(string[] args) { var jsonTUpdater = new ConfigurationUpdater(); var parseResult = new Parser(with => with.HelpWriter = null) .ParseArguments <JsonTCommand>(args); parseResult .WithParsed(opts => { jsonTUpdater.UpdateConfiguration(opts.SourcePath).GetAwaiter().GetResult(); }) .WithNotParsed(errs => HelpContent.DisplayHelp(parseResult)); }
private async Task SetSeverityHandlerAsync(ReportDiagnostic reportDiagnostic, DiagnosticData selectedDiagnostic, Project project) { try { using var token = _listener.BeginAsyncOperation(nameof(SetSeverityHandlerAsync)); using var context = _uiThreadOperationExecutor.BeginExecute( title: ServicesVSResources.Updating_severity, defaultDescription: ServicesVSResources.Updating_severity, allowCancellation: true, showProgress: true); var newSolution = await ConfigureSeverityAsync(context.UserCancellationToken).ConfigureAwait(false); var operations = ImmutableArray.Create <CodeActionOperation>(new ApplyChangesOperation(newSolution)); using var scope = context.AddScope(allowCancellation: true, ServicesVSResources.Updating_severity); await _editHandlerService.ApplyAsync( _workspace, project.Solution, fromDocument : null, operations : operations, title : ServicesVSResources.Updating_severity, progressTracker : new UIThreadOperationContextProgressTracker(scope), cancellationToken : context.UserCancellationToken).ConfigureAwait(false); if (selectedDiagnostic.DocumentId != null) { // Kick off diagnostic re-analysis for affected document so that the configured diagnostic gets refreshed. _ = Task.Run(() => { _diagnosticService.Reanalyze(_workspace, documentIds: SpecializedCollections.SingletonEnumerable(selectedDiagnostic.DocumentId), highPriority: true); }); } } catch (OperationCanceledException) { } catch (Exception ex) when(FatalError.ReportAndCatch(ex)) { } return; // Local functions. async System.Threading.Tasks.Task <Solution> ConfigureSeverityAsync(CancellationToken cancellationToken) { var diagnostic = await selectedDiagnostic.ToDiagnosticAsync(project, cancellationToken).ConfigureAwait(false); return(await ConfigurationUpdater.ConfigureSeverityAsync(reportDiagnostic, diagnostic, project, cancellationToken).ConfigureAwait(false)); } }
private static ImmutableArray <CodeFix> GetConfigurations( Project project, IEnumerable <Diagnostic> diagnostics, CancellationToken cancellationToken ) { var result = ArrayBuilder <CodeFix> .GetInstance(); foreach (var diagnostic in diagnostics) { // First get all the relevant code style options for the diagnostic. var codeStyleOptions = ConfigurationUpdater.GetCodeStyleOptionsForDiagnostic( diagnostic, project ); if (codeStyleOptions.IsEmpty) { continue; } // For each code style option, create a top level code action with nested code actions for every valid option value. // For example, if the option value is CodeStyleOption<bool>, we will have two nested actions, one for 'true' setting and one // for 'false' setting. If the option value is CodeStyleOption<SomeEnum>, we will have a nested action for each enum field. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); var optionSet = project.Solution.Workspace.Options; var hasMultipleOptions = codeStyleOptions.Length > 1; foreach ( var( optionKey, codeStyleOption, editorConfigLocation, perLanguageOption ) in codeStyleOptions.OrderBy(t => t.optionKey.Option.Name) ) { var topLevelAction = GetCodeActionForCodeStyleOption( optionKey, codeStyleOption, editorConfigLocation, diagnostic, perLanguageOption, optionSet, hasMultipleOptions ); if (topLevelAction != null) { nestedActions.Add(topLevelAction); } } if (nestedActions.Count != 0) { // Wrap actions by another level if the diagnostic ID has multiple associated code style options to reduce clutter. var resultCodeAction = nestedActions.Count > 1 ? new TopLevelConfigureCodeStyleOptionCodeAction( diagnostic, nestedActions.ToImmutable() ) : nestedActions.Single(); result.Add(new CodeFix(project, resultCodeAction, diagnostic)); } } return(result.ToImmutableAndFree()); // Local functions TopLevelConfigureCodeStyleOptionCodeAction GetCodeActionForCodeStyleOption( OptionKey optionKey, ICodeStyleOption codeStyleOption, IEditorConfigStorageLocation2 editorConfigLocation, Diagnostic diagnostic, bool isPerLanguage, OptionSet optionSet, bool hasMultipleOptions ) { // Add a code action for every valid value of the given code style option. // We only support light-bulb configuration of code style options with boolean or enum values. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); string optionName = null; if (codeStyleOption.Value is bool) { foreach (var boolValue in s_boolValues) { AddCodeActionWithOptionValue(codeStyleOption, boolValue); } } else if (codeStyleOption.Value?.GetType() is Type t && t.IsEnum) { foreach (var enumValue in Enum.GetValues(t)) { AddCodeActionWithOptionValue(codeStyleOption, enumValue); } } if (nestedActions.Count > 0) { // If this is not a unique code style option for the diagnostic, use the optionName as the code action title. // In that case, we will already have a containing top level action for the diagnostic. // Otherwise, use the diagnostic information in the title. return(hasMultipleOptions ? new TopLevelConfigureCodeStyleOptionCodeAction( optionName, nestedActions.ToImmutable() ) : new TopLevelConfigureCodeStyleOptionCodeAction( diagnostic, nestedActions.ToImmutable() )); } return(null); // Local functions void AddCodeActionWithOptionValue(ICodeStyleOption codeStyleOption, object newValue) { // Create a new code style option value with the newValue var configuredCodeStyleOption = codeStyleOption.WithValue(newValue); // Try to get the parsed editorconfig string representation of the new code style option value if ( ConfigurationUpdater.TryGetEditorConfigStringParts( configuredCodeStyleOption, editorConfigLocation, optionSet, out var parts ) ) { // We expect all code style values for same code style option to have the same editorconfig option name. Debug.Assert(optionName == null || optionName == parts.optionName); optionName ??= parts.optionName; // Add code action to configure the optionValue. nestedActions.Add( new SolutionChangeAction( parts.optionValue, solution => ConfigurationUpdater.ConfigureCodeStyleOptionAsync( parts.optionName, parts.optionValue, diagnostic, isPerLanguage, project, cancellationToken ) ) ); } } } }
public TrayApplicationContext( ILogger<TrayApplicationContext> logger, TrayContextMenuStrip contextMenu, NotifyIconManager notifyIconManager, AppState appState, StartupManager startupManager, ConfigurationUpdater configurationUpdater ) { if (notifyIconManager == null) { throw new ArgumentNullException(nameof(notifyIconManager)); } if (appState == null) { throw new ArgumentNullException(nameof(appState)); } if (startupManager == null) { throw new ArgumentNullException(nameof(startupManager)); } if (configurationUpdater == null) { throw new ArgumentNullException(nameof(configurationUpdater)); } this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.contextMenu = contextMenu ?? throw new ArgumentNullException(nameof(contextMenu)); notifyIconManager.NotifyIcon.ContextMenuStrip = contextMenu; appState.OnMachineStateChange += (object _, MachineStateChangeEventArgs __) => UpdateContextMenu(); appState.OnConfigurationChange += (object _, ConfigurationChangeEventArgs e) => { if (e.NewConfiguration.StartWithWindows != startupManager.IsEnabled()) { if (e.NewConfiguration.StartWithWindows) { startupManager.EnableStartup(); } else { startupManager.DisableStartup(); } } if (e.NewConfiguration.ShowTrayIcon) { notifyIconManager.ShowIcon(); } else { notifyIconManager.HideIcon(); } CreateContextMenu(); }; if (appState.Configuration.ShowTrayIcon) { notifyIconManager.ShowIcon(); } else if (!Program.IsAutoStarting()) { // If the program is not auto-starting and the tray icon is not visible the user launched the // application manually and it was not already running. We will show the configuration under the // assumption they are looking for it. configurationUpdater.ShowConfigurationForm(); } CreateContextMenu(); }