Source

Resharper Spell Checker / ReSpeller / Analyzers / AnalyzerHelper.cs

Full commit
using System;
using System.Collections.Generic;
using System.Text;
using JetBrains.Application;
using JetBrains.DocumentModel;
using JetBrains.ReSharper.Daemon.Stages;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Naming;
using JetBrains.ReSharper.Psi.Naming.Impl;
using JetBrains.ReSharper.Psi.Naming.Interfaces;
using JetBrains.ReSharper.Psi.Naming.Settings;
using JetBrains.ReSharper.Psi.Tree;
using ReSpeller.Highlightings;
using ReSpeller.SpellEngine;

namespace ReSpeller.Analyzers
{
  static class AnalyzerHelper
  {
    public static void GenerateRangeBasedHighlightings(ISpellChecker checker, IHighlightingConsumer consumer, IFile file, DocumentRange range, 
                                                       Func<DocumentRange, TextRangeTypoHighlighting> highlightingCreator)
    {
      string text = range.GetText();
      if (text == null)
        return;
      List<TextPart> textParts = TextSplitter.Split(text);
      foreach (TextPart part in textParts)
      {
        if (part.Type == TextPartType.Word && !checker.CheckWordSpelling(part.Text))
        {
          DocumentRange partRange = RangeUtils.GetPartRange(range, part);
          consumer.AddHighlighting(highlightingCreator(partRange), partRange, file);
        }
      }      
    }

    public static void GenerateIdentifierHighlightings(IHighlightingConsumer consumer, List<TextPart> innerNameParts, DocumentRange elementRange, string prefix,
                                                       string suffix, IDeclaration declaration,
                                                       bool isNamespace, ITreeNode treeNode, IDeclaredElement declaredElement)
    {
      var partsForSuggest = innerNameParts;
      if (isNamespace)
      {
        partsForSuggest = DecomposeFullNamespace(treeNode, declaration as INamespaceDeclaration,
          out prefix, out suffix);
      }
      var checker = Shell.Instance.GetComponent<ISpellChecker>();
      
      foreach (TextPart p in innerNameParts)
      {
        if (p.Type == TextPartType.Word && p.Text.Length > 2)
        {
          if (!checker.CheckWordSpelling(p.Text))
          {
            DocumentRange partRange = RangeUtils.GetPartRange(elementRange, p, prefix.Length, suffix.Length);
            consumer.AddHighlighting(new IdentifierTypoHighlighting(treeNode, declaration, declaredElement, p, isNamespace, partsForSuggest, prefix, suffix),
                                     partRange, treeNode.GetContainingFile());
          }
        }
      }
    }

    public static List<TextPart> DecomposeName(ITreeNode treeNode, IDeclaredElement declaredElement, out string prefix,
                                                out string suffix)
    {
      return DecomposeName(treeNode, declaredElement, treeNode.GetText(), out prefix, out suffix);
    }

    public static List<TextPart> DecomposeNamespace(ITreeNode treeNode, INamespaceDeclaration namespaceDeclaration, out string prefix, out string suffix)
    {
      return DecomposeName(treeNode, namespaceDeclaration.DeclaredElement, namespaceDeclaration.DeclaredName, out prefix, out suffix);
    }

    public static List<TextPart> DecomposeFullNamespace(ITreeNode treeNode, INamespaceDeclaration namespaceDeclaration, out string prefix, out string suffix)
    {
      return DecomposeName(treeNode, namespaceDeclaration.DeclaredElement, namespaceDeclaration.QualifiedName, out prefix, out suffix);
    }

    public static List<TextPart> DecomposeName(ITreeNode treeNode, IDeclaredElement declaredElement, string fullName, out string prefix,
                                                out string suffix)
    {     
      IPsiServices psiServices = treeNode.GetPsiServices();
      NamingManager namingManager = psiServices.Naming;
      PsiLanguageType psiLanguageType = treeNode.GetKnownLanguage();
      IPsiSourceFile psiSourceFile = treeNode.GetSourceFile();

      NamingPolicy policy;
      if (declaredElement == null)
      {
        policy = psiServices.Naming.Policy
                            .GetPolicy(NamedElementKinds.Other, psiLanguageType, psiSourceFile);
      }
      else
      {
        policy = psiServices.Naming.Policy
        .GetPolicy(declaredElement, psiLanguageType, psiSourceFile);
      }

      INamingPolicyProvider namingPolicyProvider = psiServices.Naming.Policy
        .GetPolicyProvider(psiLanguageType, psiSourceFile);

      //string shortName = declaration.ShortName;

      Name name = namingManager.Parsing.Parse(fullName, policy.NamingRule, namingPolicyProvider);
      var sb = new StringBuilder(fullName.Length);
      foreach (var innerElement in name.InnerElements)
      {
        sb.Append(innerElement.Text);
      }
      string innerName = sb.ToString();
      List<TextPart> innerNameParts = TextSplitter.Split(innerName);

      prefix = name.NamePrefix.Text;
      suffix = name.NameSuffix.Text;
      return innerNameParts;
    }
  }
}