Commits

Nerzhul500  committed d0b295e

SpellChecker usages replaced by ISpellChecker everywhere
Some refactoring of SpellChecker

  • Participants
  • Parent commits dcb7b2e
  • Branches spellengine_refactoring

Comments (0)

Files changed (16)

File ReSpeller/Actions/AddArbitraryWordHelper.cs

         promptWinForm.FormBorderStyle = FormBorderStyle.FixedDialog;
         if (promptWinForm.ShowDialog())
         {
-          Shell.Instance.GetComponent<SpellChecker>().AddWordToUserDict(promptWinForm.Value);
+          Shell.Instance.GetComponent<ISpellChecker>().AddWordToUserDict(promptWinForm.Value);
         }
       }
     }

File ReSpeller/Analyzers/AnalyzerHelper.cs

 {
   static class AnalyzerHelper
   {
-    public static void GenerateRangeBasedHighlightings(SpellChecker checker, IHighlightingConsumer consumer, IFile file, DocumentRange range, 
+    public static void GenerateRangeBasedHighlightings(ISpellChecker checker, IHighlightingConsumer consumer, IFile file, DocumentRange range, 
                                                        Func<DocumentRange, TextRangeTypoHighlighting> highlightingCreator)
     {
       string text = range.GetText();
                                                        string suffix, IDeclaredElement declaredElement,
                                                        bool isNamespace, ITreeNode treeNode)
     {
-      var checker = Shell.Instance.GetComponent<SpellChecker>();
+      var checker = Shell.Instance.GetComponent<ISpellChecker>();
       
       foreach (TextPart p in innerNameParts)
       {

File ReSpeller/Analyzers/CommentTypoAnalyzer.cs

   [ElementProblemAnalyzer(new[] { typeof(IComment) })]
   public class CommentTypoAnalyzer : ElementProblemAnalyzer<IComment>
   {
-    private readonly SpellChecker myChecker = Shell.Instance.GetComponent<SpellChecker>();
+    private readonly ISpellChecker myChecker = Shell.Instance.GetComponent<ISpellChecker>();
 
     protected override void Run(IComment element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
     {

File ReSpeller/Analyzers/StringLiteralTypoAnalyzer.cs

   [ElementProblemAnalyzer(new[] { typeof(ILiteralExpression) })]
   public class StringLiteralTypoAnalyzer : ElementProblemAnalyzer<ILiteralExpression>
   {
-    private readonly SpellChecker myChecker = Shell.Instance.GetComponent<SpellChecker>();
+    private readonly ISpellChecker myChecker = Shell.Instance.GetComponent<ISpellChecker>();
 
     protected override void Run(ILiteralExpression element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
     {

File ReSpeller/Analyzers/XmlTypoAnalysis.cs

 {
   internal class XmlTypoAnalysis : XmlAnalysis
   {
-    private readonly SpellChecker myChecker = Shell.Instance.GetComponent<SpellChecker>();
+    private readonly ISpellChecker myChecker = Shell.Instance.GetComponent<ISpellChecker>();
 
     public override bool InteriorShouldBeProcessed(ITreeNode element)
     {

File ReSpeller/Bulbs/AddToDictionaryBulbItem.cs

 
     public void Execute(ISolution solution, ITextControl textControl)
     {
-      var spellChecker = Shell.Instance.GetComponent<SpellChecker>();
+      var spellChecker = Shell.Instance.GetComponent<ISpellChecker>();
       spellChecker.AddWordToUserDict(myNewWord);
       Daemon.GetInstance(solution).Invalidate();
     }

File ReSpeller/Bulbs/AddToInternalDictionaryBulbItem.cs

 
     public void Execute(ISolution solution, ITextControl textControl)
     {
-      var spellChecker = Shell.Instance.GetComponent<SpellChecker>();
+      var spellChecker = Shell.Instance.GetComponent<ISpellChecker>();
       spellChecker.AddWordToCustomDict(myNewWord);
       Daemon.GetInstance(solution).Invalidate();
     }

File ReSpeller/QuickFixes/TypoQuickFix.cs

   [QuickFix]
   class TypoQuickFix : IQuickFix
   {
-    private readonly SpellChecker myChecker = Shell.Instance.GetComponent<SpellChecker>();
+    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>();

File ReSpeller/ReSpeller.csproj

     <Compile Include="Settings\ReSpellerSettingsControl.xaml.cs">
       <DependentUpon>ReSpellerSettingsControl.xaml</DependentUpon>
     </Compile>
+    <Compile Include="SpellEngine\ConfigurableWordChecker.cs" />
     <Compile Include="SpellEngine\Constants.cs" />
     <Compile Include="SpellEngine\Dictionaries\DictionaryFactory.cs" />
     <Compile Include="SpellEngine\Dictionaries\FileDictionaryStorage.cs" />
     <Compile Include="SpellEngine\Dictionaries\HunspellEngine.cs" />
-    <Compile Include="SpellEngine\Dictionaries\HunspellLanguageDictionary.cs" />
     <Compile Include="SpellEngine\Dictionaries\IDictionaryStorage.cs" />
     <Compile Include="SpellEngine\Dictionaries\IDictionaryEngine.cs" />
     <Compile Include="SpellEngine\Dictionaries\ILanguageDictionary.cs" />
     <Compile Include="SpellEngine\ISpellChecker.cs" />
     <Compile Include="SpellEngine\Dictionaries\IUserInternalDictionary.cs" />
+    <Compile Include="SpellEngine\IWordSuggestor.cs" />
     <Compile Include="SpellEngine\NamingStyleConverter.cs" />
     <Compile Include="SpellEngine\RangeUtils.cs" />
     <Compile Include="SpellEngine\SpellChecker.cs" />
+    <Compile Include="SpellEngine\SpellCheckerConfig.cs" />
     <Compile Include="SpellEngine\SuggestionGenerator.cs" />
     <Compile Include="SpellEngine\TextSplitter.cs" />
     <Compile Include="SpellEngine\Dictionaries\UserInternalDictionary.cs" />
     </None>
     <None Include="..\dic\en_US_custom.dic">
       <Link>dic\en_US_custom.dic</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
     <None Include="packages.config" />
   </ItemGroup>
     </Content>
   </ItemGroup>
   <PropertyGroup>
-    <ReSharperSdkTargets Condition=" '$(ReSharperSdkTargets)' == '' ">$(MSBuildExtensionsPath)\JetBrains\ReSharper.SDK\v7.0</ReSharperSdkTargets>
+    <ReSharperSdkTargets Condition=" '$(ReSharperSdkTargets)' == '' ">$(MSBuildExtensionsPath)\JetBrains\ReSharper.SDK\v7.1</ReSharperSdkTargets>
   </PropertyGroup>
   <Import Project="$(ReSharperSdkTargets)\Plugin.Targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

File ReSpeller/Settings/ReSpellerSettingsControl.xaml.cs

 using System.Windows.Controls.Primitives;
+using JetBrains.Application;
 using JetBrains.DataFlow;
 using JetBrains.UI.CrossFramework;
 using JetBrains.UI.Options;
 using JetBrains.UI.Options.OptionPages;
 using JetBrains.Application.Settings;
+using ReSpeller.SpellEngine;
 using Xceed.Wpf.Toolkit;
 
 namespace ReSpeller.Settings
 
     public bool OnOk()
     {
+      var spellChecker = Shell.Instance.GetComponent<ISpellChecker>();
+      spellChecker.UpdateConfig();
       return true;
     }
 

File ReSpeller/SpellEngine/ConfigurableWordChecker.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ReSpeller.SpellEngine.Dictionaries;
+
+namespace ReSpeller.SpellEngine
+{
+  public class ConfigurableWordChecker
+  {
+    private const int MaxLengthForSplit = 30;
+
+    private readonly List<ILanguageDictionary> myDictionaries;
+
+    public ConfigurableWordChecker(List<ILanguageDictionary> dictionaries)
+    {
+      myDictionaries = dictionaries;
+      Config = new SpellCheckerConfig();
+    }
+
+    public SpellCheckerConfig Config { get; set; }
+
+    public bool Check(string word)
+    {
+      if (word.Length < Config.MinWordLength)
+        return true;
+      // try to check in many styles
+      bool wholeWordCheck = CheckInDictionaries(word.ToLower())
+        || CheckInDictionaries(word.ToUpper())
+        || CheckInDictionaries(NamingStyleConverter.Convert(word, "Aaa"));
+      if (wholeWordCheck)
+        return true;
+
+      //try to split into pair of words
+      if (Config.SplitInPairs)
+      {
+        if (word.Length < 4 || word.Length > MaxLengthForSplit) //min size of each word == 2, e.g. inplace -> in+place
+          //also very long words will be ignored
+          return false;
+        for (int i = 2; i < word.Length - 1; ++i)
+        {
+          string first = word.Substring(0, i);
+          string second = word.Substring(i);
+          if (CheckInDictionaries(first) && CheckInDictionaries(second))
+            return true;
+        }
+      }
+      return false;
+    }
+
+    private bool CheckInDictionaries(string word)
+    {
+      return myDictionaries.Any(dictionary => dictionary.Check(word));
+    }    
+  }
+}

File ReSpeller/SpellEngine/Dictionaries/FileDictionaryStorage.cs

     {
       myFileName = fileName;
       if (!File.Exists(fileName))
+      {
+        string directoryName = Path.GetDirectoryName(fileName);
+        if (!Directory.Exists(directoryName))
+          Directory.CreateDirectory(directoryName);
         File.Create(fileName).Dispose();
+      }
+        
     }
 
     public void AddWord(string word)

File ReSpeller/SpellEngine/ISpellChecker.cs

     List<string> Suggestions(string word);
     void AddWordToUserDict(string word);
     void AddWordToCustomDict(string word);
+    void UpdateConfig();
   }
 }

File ReSpeller/SpellEngine/IWordSuggestor.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ReSpeller.SpellEngine.Dictionaries;
+
+namespace ReSpeller.SpellEngine
+{
+  public interface IWordSuggestor
+  {
+    List<string> Suggest(string word);
+  }
+
+  class SingleDictionarySuggestor : IWordSuggestor
+  {
+    private readonly ILanguageDictionary myDictionary;
+
+    public SingleDictionarySuggestor(ILanguageDictionary dictionary)
+    {
+      myDictionary = dictionary;
+    }
+
+    public List<string> Suggest(string word)
+    {
+      List<string> result = myDictionary.Suggests(word)
+          .Where(s => s.ToLower() != word.ToLower()) // filter suggests not equals original word
+          .Select(s => NamingStyleConverter.Convert(s, word)).ToList(); // convert style
+      return result.Any() ? result.ToList() : new List<string> { word };
+    }
+  }
+}

File ReSpeller/SpellEngine/SpellChecker.cs

     private const string CurrentLanguage = "en_us";
 
     private readonly UserInternalDictionary myDictionary;
-    private const int MaxLengthForSplit = 30;
-    private readonly string myPluginPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof (SpellChecker)).Location);
+    private readonly string myPluginPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof (ISpellChecker)).Location);
     private volatile object mySync = new object();
+    private readonly ConfigurableWordChecker myWordChecker;
+    private readonly IWordSuggestor myWordSuggestor;
 
     public SpellChecker(ISettingsStore store)
     {
       HunspellEngine.NativeDllPath = myPluginPath;
       string mainDictDir = Path.Combine(myPluginPath, Constants.MainDictSubDir);
       string userDictDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Constants.UserDictSubDir);
-      //var dictionary = new HunspellLanguageDictionary(mainDictDir, CurrentLanguage);
       var userStorage = new FileDictionaryStorage(Path.Combine(userDictDir, CurrentLanguage + "." + Constants.DictExt));
       var internalStorage = new FileDictionaryStorage(Path.Combine(mainDictDir, CurrentLanguage + Constants.InternalDictSuffix + "." + Constants.DictExt));
       HunspellEngine hunspellEngine = HunspellEngine.CreateForLanguage(mainDictDir, CurrentLanguage);
       myDictionary = new UserInternalDictionary(hunspellEngine, CurrentLanguage, userStorage, internalStorage);
+      myWordChecker = new ConfigurableWordChecker(new List<ILanguageDictionary> {myDictionary});
+      myWordSuggestor = new SingleDictionarySuggestor(myDictionary);
     }
 
     #region IDisposable Members
     #endregion
 
     public bool CheckWordSpelling(string word)
-    {
-      var settings = myStore.GetKey<ReSpellerSettings>(SettingsOptimization.DoMeSlowly);
-      if (word.Length < settings.MinWordLength)
-        return true;
+    {     
       lock (mySync)
       {
-        // try to check in many styles
-        bool wholeWordCheck = myDictionary.Check(word.ToLower())
-          || myDictionary.Check(word.ToUpper())
-          || myDictionary.Check(NamingStyleConverter.Convert(word, "Aaa"));
-        if (wholeWordCheck)
-          return true;
-        
-        //try to split into pair of words
-        if (settings.SplitInPairs)
-        {
-          if (word.Length < 4 || word.Length > MaxLengthForSplit) //min size of each word == 2, e.g. inplace -> in+place
-            //also very long words will be ignored
-            return false;
-          for (int i = 2; i < word.Length - 1; ++i)
-          {
-            string first = word.Substring(0, i);
-            string second = word.Substring(i);
-            if (myDictionary.Check(first) && myDictionary.Check(second))
-              return true;
-          }
-        }
-        return false;
+        return myWordChecker.Check(word);
       }
     }
 
     {
       lock (mySync)
       {
-        List<string> result = myDictionary.Suggests(word)
-          .Where(s => s.ToLower() != word.ToLower()) // filter suggests not equals original word
-          .Select(s => NamingStyleConverter.Convert(s, word)).ToList(); // convert style
-        return result.Any() ? result.ToList() : new List<string> {word};
+        return myWordSuggestor.Suggest(word);
       }
     }
 
         myDictionary.AddToInternalDict(word);
       }
     }
+
+    public void UpdateConfig()
+    {
+      var settings = myStore.GetKey<ReSpellerSettings>(SettingsOptimization.DoMeSlowly);
+      myWordChecker.Config.MinWordLength = settings.MinWordLength;
+      myWordChecker.Config.SplitInPairs = settings.SplitInPairs;
+    }
   }
 }

File ReSpeller/SpellEngine/SpellCheckerConfig.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ReSpeller.SpellEngine
+{
+  public class SpellCheckerConfig
+  {
+    public bool SplitInPairs { get; set; }
+    public int MinWordLength { get; set; }
+  }
+}