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));
            }
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
 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);
 }
Exemplo n.º 4
0
        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;
        }
Exemplo n.º 5
0
        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();
        }
Exemplo n.º 6
0
        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();
        }