Commits

Anonymous committed df14390

Many exceptions fixed.
Xaml support improved.

  • Participants
  • Parent commits f0ec08d
  • Branches resharper8

Comments (0)

Files changed (17)

ReSpeller.RSTests/ReSpeller8.x.RSTests.csproj

   <ItemGroup>
     <Compile Include="SpellEngine\SuggestionGeneratorStub.cs" />
     <Compile Include="VBasicHighlightingsTest.cs" />
+    <Compile Include="XamlHighlightingTest.cs" />
     <Compile Include="XmlHighlightingsTest.cs" />
     <Compile Include="CSharpHighlightingsTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

ReSpeller.RSTests/XamlHighlightingTest.cs

+using JetBrains.Application.Settings;
+using JetBrains.ReSharper.Daemon;
+using JetBrains.ReSharper.Daemon.Xaml.Test;
+using NUnit.Framework;
+using ReSpeller.Highlightings;
+
+namespace ReSpeller.RSTests
+{
+  [TestFixture]
+  public class XamlHighlightingTest : XamlHighlightingTestBase
+  {
+    protected override bool HighlightingPredicate(IHighlighting highlighting, IContextBoundSettingsStore settingsstore)
+    {
+      return highlighting is MarkupTextTypoHighlighting
+             || highlighting is CommentTypoHighlighting
+             || highlighting is MarkupAttributeTypoHighlighting
+             || highlighting is IdentifierTypoHighlighting;
+    }
+
+    protected override string RelativeTestDataPath
+    {
+      get { return @"Highlightings\Xaml"; }
+    }
+
+    [Test]
+    public void Test01()
+    {
+      DoNamedTest();
+    }
+  }
+}

ReSpeller.RSTests/XmlHighlightingsTest.cs

 using JetBrains.ReSharper.Daemon;
 using JetBrains.ReSharper.Daemon.CSharp;
 using JetBrains.Application.Settings;
+using JetBrains.ReSharper.Daemon.Test;
+using JetBrains.ReSharper.Psi;
+using JetBrains.ReSharper.Psi.Xml;
 using NUnit.Framework;
 using ReSpeller.Highlightings;
 
 namespace ReSpeller.RSTests
 {
   [TestFixture]
-  public class XmlHighlightingTest : CSharpHighlightingTestBase
+  public class XmlHighlightingTest : HighlightingTestBase
   {
     protected override bool HighlightingPredicate(IHighlighting highlighting, IContextBoundSettingsStore settingsstore)
     {
         || highlighting is MarkupAttributeTypoHighlighting;
     }
 
+    protected override PsiLanguageType CompilerIdsLanguage
+    {
+      get { return XmlLanguage.Instance; }
+    }
+
     protected override string RelativeTestDataPath
     {
       get { return @"Highlightings\Xml"; }

ReSpeller.RSTests/test/data/Highlightings/Xaml/Test01.xaml

+<UserControl x:Class="ConsoleApplication.WrongwordControl"                   
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             mc:Ignorable="d"  
+             d:DesignHeight="300" d:DesignWidth="300">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <Style x:Key="WrongwordStyle"></Style>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid>
+         <Button Name="ButtonWrongword" Content="OtherWrongword" Margin="0,-16,0,16">
+             Some wrongword text
+         </Button>      
+         <!-- some wrongword comment -->
+    </Grid>
+</UserControl>

ReSpeller.RSTests/test/data/Highlightings/Xaml/Test01.xaml.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ConsoleApplication
+{
+  /// <summary>
+  /// Interaction logic for UserControl1.xaml
+  /// </summary>
+  public partial class WrongwordControl : UserControl
+  {
+    public WrongwordControl()
+    {
+      InitializeComponent();
+      ButtonWrongword.Content = 1;
+    }
+  }
+}

ReSpeller.RSTests/test/data/Highlightings/Xaml/Test01.xaml.gold

+<UserControl x:Class="ConsoleApplication.|Wrongword|(0)Control"                   
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             mc:Ignorable="d"  
+             d:DesignHeight="300" d:DesignWidth="300">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <Style x:Key="|Wrongword|(1)Style"></Style>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid>
+         <Button Name="Button|Wrongword|(2)" Content="Other|Wrongword|(3)" Margin="0,-16,0,16">
+             Some |wrongword|(4) text
+         </Button>      
+         <!-- some |wrongword|(5) comment -->
+    </Grid>
+</UserControl>
+---------------------------------------------------------
+(0): ReSharper Suggestion: Typo in identifier: "Wrongword"
+(1): ReSharper Suggestion: Typo in identifier: "Wrongword"
+(2): ReSharper Suggestion: Typo in identifier: "Wrongword"
+(3): ReSharper Suggestion: Typo in markup attribute value: "Wrongword"
+(4): ReSharper Suggestion: Typo in markup text: "wrongword"
+(5): ReSharper Suggestion: Typo in comment: "wrongword"

ReSpeller/Analyzers/AnalyzerHelper.cs

                                                        Func<DocumentRange, TextRangeTypoHighlighting> highlightingCreator)
     {
       string text = range.GetText();
+      if (text == null)
+        return;
       List<TextPart> textParts = TextSplitter.Split(text);
       foreach (TextPart part in textParts)
       {
 
     public static void GenerateIdentifierHighlightings(IHighlightingConsumer consumer, List<TextPart> innerNameParts, DocumentRange elementRange, string prefix,
                                                        string suffix, IDeclaration declaration,
-                                                       bool isNamespace, ITreeNode treeNode)
+                                                       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 (!checker.CheckWordSpelling(p.Text))
           {
             DocumentRange partRange = RangeUtils.GetPartRange(elementRange, p, prefix.Length, suffix.Length);
-            consumer.AddHighlighting(new IdentifierTypoHighlighting(treeNode, declaration, p, isNamespace),
+            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 DoDecomposeName(treeNode, declaredElement, treeNode.GetText(), out prefix, out 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 DoDecomposeName(treeNode, namespaceDeclaration.DeclaredElement, namespaceDeclaration.DeclaredName, out prefix, out 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 DoDecomposeName(treeNode, namespaceDeclaration.DeclaredElement, namespaceDeclaration.QualifiedName, out prefix, out suffix);
+      return DecomposeName(treeNode, namespaceDeclaration.DeclaredElement, namespaceDeclaration.QualifiedName, out prefix, out suffix);
     }
 
-    private static List<TextPart> DoDecomposeName(ITreeNode treeNode, IDeclaredElement declaredElement, string fullName, out string prefix,
+    public static List<TextPart> DecomposeName(ITreeNode treeNode, IDeclaredElement declaredElement, string fullName, out string prefix,
                                                 out string suffix)
     {     
       IPsiServices psiServices = treeNode.GetPsiServices();

ReSpeller/Analyzers/IdentifierTypoAnalyzer.cs

         elementRange = elementRange.ExtendLeft(namespaceDeclaration.DeclaredName.Length - element.Name.Length);
       }
           
-      AnalyzerHelper.GenerateIdentifierHighlightings(consumer, innerNameParts, elementRange, prefix, suffix, declaration, isNamespace, treeNode);
+      AnalyzerHelper.GenerateIdentifierHighlightings(consumer, innerNameParts, elementRange, prefix, suffix, declaration, isNamespace, treeNode, declaredElement);
     }
 
     #endregion

ReSpeller/Analyzers/XmlTypoAnalysis.cs

+using System.Collections.Generic;
 using JetBrains.Application;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon.Stages;
 using JetBrains.ReSharper.Daemon.Xml.Stages;
+using JetBrains.ReSharper.Psi.BuildScripts.Tree;
 using JetBrains.ReSharper.Psi.Tree;
+using JetBrains.ReSharper.Psi.Xaml.Tree;
 using JetBrains.ReSharper.Psi.Xml.Impl.Tree;
 using JetBrains.ReSharper.Psi.Xml.Tree;
 using JetBrains.ReSharper.Psi.Xml.XmlDocComments;
 
     public override void ProcessBeforeInterior(ITreeNode element, IHighlightingConsumer highlightings)
     {
-      if (element.PathToRoot().Count(node => node is InjectedPsiHolderNode) > 0)
-        return; // doc comment, will be processed by comment analyzer
+      IFile containingFile = element.GetContainingFile();
+      // ignore project and build files
+      if (containingFile is IBuildFile)
+        return;
+      DocumentRange documentRange = element.GetDocumentRange();
+      if (!documentRange.IsValid())
+        return;
+
+      bool isDocComment = element.GetContainingNode<InjectedPsiHolderNode>() != null;
+      if (isDocComment)
+        return;
+
       if (element is XmlComment)
       {
         var xmlComment = element as XmlComment;
         DocumentRange commentBodyRange = xmlComment.CommentBody.GetDocumentRange();
-        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, element.GetContainingFile(), commentBodyRange, 
+        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, containingFile, commentBodyRange,
           range => new CommentTypoHighlighting(range));
       }
-      if (element is IXmlValueToken)
+      else if (element is IDeclarationNameElement)
       {
-        var xmlValueToken = element as IXmlValueToken;
-        DocumentRange xmlValueTokenRange = xmlValueToken.GetDocumentRange();
-        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, element.GetContainingFile(), xmlValueTokenRange, 
-          range => new MarkupAttributeTypoHighlighting(range));
+        var declarationNameElement = element as IDeclarationNameElement;
+        var declaration = declarationNameElement.GetContainingNode<IDeclaration>(
+            it => it.GetNameRange().StrictIntersects(declarationNameElement.GetTreeTextRange()));
+        if (declaration == null)
+          return;
+        var declaredName = declarationNameElement.DeclaredName;
+        var declaredElement = declaration.DeclaredElement;
+        string prefix;
+        string suffix;
+        var nameDocRange = declaration.GetNameDocumentRange();
+
+        List<TextPart> decomposedName = AnalyzerHelper.DecomposeName(element, declaredElement, declaredName,
+          out prefix, out suffix);
+        AnalyzerHelper.GenerateIdentifierHighlightings(highlightings, decomposedName, nameDocRange, prefix,
+          suffix, declaration, false, declarationNameElement, declaredElement);
+      }
+      else if (element is IXmlAttributeValue)
+      {
+        var xmlAttributeValue = element as IXmlAttributeValue;
+        var declaration = xmlAttributeValue.GetContainingNode<IDeclaration>(
+          it => it.GetNameRange().StrictIntersects(xmlAttributeValue.GetTreeTextRange()));
+        if (declaration != null)
+        {
+          return;
+        }
+        var referenceCollection = xmlAttributeValue.GetReferences();
+        // if we have references on the node, don't check text
+        if (referenceCollection.Any())
+          return;
+        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, containingFile, documentRange,
+          range =>
+            isDocComment
+              ? new CommentTypoHighlighting(range) as TextRangeTypoHighlighting
+              : new MarkupAttributeTypoHighlighting(range));
+
       }
       else if (element is XmlFloatingTextToken)
       {
         var tokenNode = element as XmlFloatingTextToken;
-        if (tokenNode.NodeType.ToString() != "TEXT")
+        if (tokenNode.NodeType != tokenNode.XmlTokenTypes.TEXT)
           return;
         DocumentRange xmlFloatingTokenRange = tokenNode.GetDocumentRange();
-        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, element.GetContainingFile(), xmlFloatingTokenRange, 
-          range => new MarkupTextTypoHighlighting(range));
+        AnalyzerHelper.GenerateRangeBasedHighlightings(myChecker, highlightings, containingFile, xmlFloatingTokenRange,
+          range =>
+            isDocComment
+              ? new CommentTypoHighlighting(range) as TextRangeTypoHighlighting
+              : new MarkupTextTypoHighlighting(range));
       }
     }
   }

ReSpeller/Bulbs/AdvancedTypoRenameBulbItem.cs

       }
       else
       {
+        var searchDomainFactory = solution.GetComponent<SearchDomainFactory>();
         workflow = new TypoRenameWorkflow(suggests, solution.GetComponent<IShellLocks>(),
-                                          solution.GetComponent<SearchDomainFactory>(),
+                                          searchDomainFactory,
                                           RenameRefactoringService.Instance,
                                           solution,
                                           "TypoRename");

ReSpeller/Highlightings/CommentTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon;
 
 namespace ReSpeller.Highlightings
 {
   [ConfigurableSeverityHighlighting(SeverityId,
-    "CSHARP,VBASIC,Razor,ASPX,XML,RESX,XAML,ASXX", OverlapResolve = OverlapResolveKind.NONE,
+    "CSHARP,VBASIC,XML,RESX,XAML", OverlapResolve = OverlapResolveKind.NONE,
     ToolTipFormatString = ToolTipFormatString)]
   public class CommentTypoHighlighting : TextRangeTypoHighlighting
   {
     private const string ToolTipFormatString = "Typo in comment: \"{0}\"";
     internal const string SeverityId = "CommentTypo";
 
-    public CommentTypoHighlighting(DocumentRange range) : base(range)
+    public CommentTypoHighlighting(DocumentRange range)
+      : base(range)
     {
     }
 
-    public override string ToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); }}
-    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); } }
+    public override string ToolTip { get { return string.Format(ToolTipFormatString, Text); } }
+    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Text); } }
   }
 }

ReSpeller/Highlightings/IdentifierTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.ReSharper.Daemon;
+using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.Tree;
 using ReSpeller.SpellEngine;
 
 namespace ReSpeller.Highlightings
 {
   [ConfigurableSeverityHighlighting(SeverityId,
-    "CSHARP,VBASIC,Razor,ASPX,ASXX", OverlapResolve = OverlapResolveKind.NONE,
+    "CSHARP,VBASIC,Razor,ASPX,ASXX,XAML", OverlapResolve = OverlapResolveKind.NONE,
     ToolTipFormatString = ToolTipFormatString)]
   public class IdentifierTypoHighlighting : IHighlighting
   {
     internal const string SeverityId = "IdentifierTypo";
     private const string ToolTipFormatString = "Typo in identifier: \"{0}\"";
+
     private readonly ITreeNode myTreeNode;
     private readonly IDeclaration myDeclaration;
+    private readonly IDeclaredElement myDeclaredElement;
     private readonly bool myIsNamespace;
     private readonly TextPart myWrongPart;
 
-    public IdentifierTypoHighlighting(ITreeNode treeNode, IDeclaration declaration, TextPart wrongPart, bool isNamespace)
+    public IdentifierTypoHighlighting(ITreeNode treeNode, IDeclaration declaration, IDeclaredElement declaredElement, TextPart wrongPart, bool isNamespace,
+      List<TextPart> innerNameParts, string prefix, string suffix)
     {
+      InnerNameParts = innerNameParts;
+      Prefix = prefix;
+      Suffix = suffix;
       myTreeNode = treeNode;
       myDeclaration = declaration;
+      myDeclaredElement = declaredElement;
       myWrongPart = wrongPart;
       myIsNamespace = isNamespace;
     }
 
+    public List<TextPart> InnerNameParts { get; private set; }
+    public string Prefix { get; private set; }
+    public string Suffix { get; private set; }
+
     public bool IsNamespace
     {
       get { return myIsNamespace; }
       get { return myTreeNode; }
     }
 
+    public IDeclaredElement DeclaredElement
+    {
+      get { return myDeclaredElement; }
+    }
+
     public bool IsValid()
     {
       return true;

ReSpeller/Highlightings/MarkupAttributeTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon;
 
 namespace ReSpeller.Highlightings
 {
   [ConfigurableSeverityHighlighting(SeverityId,
-    "XML,RESX,XAML,Razor,ASPX", OverlapResolve = OverlapResolveKind.NONE,
+    "XML,RESX,XAML,HTML,Razor,ASPX", OverlapResolve = OverlapResolveKind.NONE,
     ToolTipFormatString = ToolTipFormatString)]
   public class MarkupAttributeTypoHighlighting : TextRangeTypoHighlighting
   {
     {
     }
 
-    public override string ToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); }}
-    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); } }
+    public override string ToolTip { get { return string.Format(ToolTipFormatString, Text); }}
+    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Text); } }
   }
 }

ReSpeller/Highlightings/MarkupTextTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon;
 
 namespace ReSpeller.Highlightings
 {
   [ConfigurableSeverityHighlighting(SeverityId,
-    "XML,RESX,XAML,Razor,ASPX", OverlapResolve = OverlapResolveKind.NONE,
+    "XML,RESX,XAML,HTML,Razor,ASPX", OverlapResolve = OverlapResolveKind.NONE,
     ToolTipFormatString = ToolTipFormatString)]
   public class MarkupTextTypoHighlighting : TextRangeTypoHighlighting
   {
     private const string ToolTipFormatString = "Typo in markup text: \"{0}\"";
     internal const string SeverityId = "MarkupTextTypo";
 
-    public MarkupTextTypoHighlighting(DocumentRange range) : base(range)
+    public MarkupTextTypoHighlighting(DocumentRange range)
+      : base(range)
     {
     }
 
-    public override string ToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); }}
-    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); } }
+    public override string ToolTip { get { return string.Format(ToolTipFormatString, Text); } }
+    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Text); } }
   }
 }

ReSpeller/Highlightings/StringLiteralTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon;
 
 namespace ReSpeller.Highlightings
 {
   [ConfigurableSeverityHighlighting(SeverityId,
-    "CSHARP,VBASIC,Razor,ASPX,ASXX", OverlapResolve = OverlapResolveKind.NONE,
+    "CSHARP,VBASIC,JAVA_SCRIPT,Razor,ASPX,ASXX", OverlapResolve = OverlapResolveKind.NONE,
     ToolTipFormatString = ToolTipFormatString)]
   public class StringLiteralTypoHighlighting : TextRangeTypoHighlighting
   {
     private const string ToolTipFormatString = "Typo in string: \"{0}\"";
     internal const string SeverityId = "StringLiteralTypo";
 
-    public StringLiteralTypoHighlighting(DocumentRange range) : base(range)
+    public StringLiteralTypoHighlighting(DocumentRange range)
+      : base(range)
     {
     }
 
-    public override string ToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); }}
-    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Range.GetText()); } }
+    public override string ToolTip { get { return string.Format(ToolTipFormatString, Text); } }
+    public override string ErrorStripeToolTip { get { return string.Format(ToolTipFormatString, Text); } }
   }
 }

ReSpeller/Highlightings/TextRangeTypoHighlighting.cs

+using System.Collections.Generic;
 using JetBrains.DocumentModel;
 using JetBrains.ReSharper.Daemon;
 
   {
     private readonly DocumentRange myRange;
 
+
     protected TextRangeTypoHighlighting(DocumentRange range)
     {
       myRange = range;
+      Text = range.GetText();
     }
 
     public abstract string ToolTip { get; }
     {
       return true;
     }
+
+    public string Text { get; private set; }
   }
 }

ReSpeller/QuickFixes/TypoQuickFix.cs

     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);
-                      });
+      var suggests = new AsyncValue<List<string>>(() => mySuggestionGenerator.Generate(highlighting.InnerNameParts, highlighting.Prefix, highlighting.Suffix));
 
-      myBulbItems.Add(new AdvancedTypoRenameBulbItem(highlighting.Declaration.DeclaredElement, suggests));
+      myBulbItems.Add(new AdvancedTypoRenameBulbItem(highlighting.DeclaredElement, suggests));
       string word = highlighting.WrongPart.Text;
       myBulbItems.Add(new AddToDictionaryBulbItem(word));
       myBulbItems.Add(new EditAddToDictionaryBulb(word));
     {
       myHighlighting = highlighting;
       var highlightingRange = highlighting.Range;
-      string word = highlightingRange.GetText();
+      string word = highlighting.Text;
       AsyncValue<List<string>> suggests = new AsyncValue<List<string>>(() => myChecker.Suggestions(word));
       myBulbItems.Add(new TextRangeTypoReplaceBulbItem(highlightingRange, suggests));
       myBulbItems.Add(new AddToDictionaryBulbItem(word));