Source

Resharper Spell Checker / ReSpeller / QuickFixes / TypoQuickFix.cs

Full commit
using System.Collections.Generic;
using JetBrains.Annotations;
using JetBrains.Application;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Intentions.Extensibility.Menu;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.Util;
using ReSpeller.Analyzers;
using ReSpeller.Bulbs;
using ReSpeller.Highlightings;
using ReSpeller.SpellEngine;
using ReSpeller.Util;

namespace ReSpeller.QuickFixes
{
  [QuickFix]
  internal class TypoQuickFix : IQuickFix
  {
    private readonly ISpellChecker myChecker = Shell.Instance.GetComponent<ISpellChecker>();
    private readonly SuggestionGenerator mySuggestionGenerator = Shell.Instance.GetComponent<SuggestionGenerator>();
    private readonly IHighlighting myHighlighting;
    private readonly List<IBulbItem> myBulbItems = new List<IBulbItem>();

    public TypoQuickFix([NotNull] IdentifierTypoHighlighting highlighting)
    {
      myHighlighting = highlighting;
      var suggests = new AsyncValue<List<string>>(() =>
                      {
                        string prefix;
                        string suffix;
                        List<TextPart> decomposedName = highlighting.Declaration is INamespaceDeclaration 
                          ? AnalyzerHelper.DecomposeFullNamespace(highlighting.TreeNode, highlighting.Declaration as INamespaceDeclaration, out prefix, out suffix) 
                          : AnalyzerHelper.DecomposeName(highlighting.TreeNode, highlighting.Declaration.DeclaredElement, out prefix, out suffix);
                        return mySuggestionGenerator.Generate(decomposedName, prefix, suffix);
                      });

      myBulbItems.Add(new AdvancedTypoRenameBulbItem(highlighting.Declaration.DeclaredElement, suggests));
      string word = highlighting.WrongPart.Text;
      myBulbItems.Add(new AddToDictionaryBulbItem(word));
      myBulbItems.Add(new EditAddToDictionaryBulb(word));

      AddInternalDictionaryItemDebugOnly(word);
    }

    public TypoQuickFix([NotNull] TextRangeTypoHighlighting highlighting)
    {
      myHighlighting = highlighting;
      AsyncValue<List<string>> suggests = new AsyncValue<List<string>>(() => myChecker.Suggestions(highlighting.Range.GetText()));
      myBulbItems.Add(new TextRangeTypoReplaceBulbItem(highlighting.Range, suggests));
      string word = highlighting.Range.GetText();
      myBulbItems.Add(new AddToDictionaryBulbItem(word));
      myBulbItems.Add(new EditAddToDictionaryBulb(word));
      AddInternalDictionaryItemDebugOnly(word);
    }

    private void AddInternalDictionaryItemDebugOnly(string word)
    {
#if DEBUG 
      myBulbItems.Add(new AddToInternalDictionaryBulbItem(word));
#endif
    }

    public void CreateBulbItems(BulbMenu menu, Severity severity)
    {
      BulbGroup group = menu.GetOrCreateGroup(AnchorsForBulbMenuGroups.QuickFixesAnchor);
      foreach (var bulbItem in myBulbItems)
      {
        group.AddBulbAction(AnchorsForBulbMenuGroups.QuickFixesAnchor, bulbItem, ImgThemedIcons.Icon.Id);
      }
    }

    public bool IsAvailable(IUserDataHolder cache)
    {
      return myHighlighting.IsValid();
    }
  }
}