diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index 4acc415db9..229d1c39af 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -409,6 +409,10 @@ namespace ICSharpCode.AvalonEdit.AddIn if (!CodeCompletionOptions.EnableCodeCompletion) return; + TextArea textArea = GetTextEditorFromSender(sender).TextArea; + if (textArea.ActiveInputHandler != textArea.DefaultInputHandler) + return; // deactivate CC for non-default input handlers + ITextEditor adapter = GetAdapterFromSender(sender); foreach (char c in e.Text) { diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs index 8c103d1316..f0a3ec5635 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs @@ -12,11 +12,11 @@ using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; - using ICSharpCode.Core; using ICSharpCode.FormsDesigner.Services; using ICSharpCode.FormsDesigner.UndoRedo; using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; @@ -277,7 +277,7 @@ namespace ICSharpCode.FormsDesigner serviceContainer.AddService(typeof(DesignerOptionService), new SharpDevelopDesignerOptionService()); serviceContainer.AddService(typeof(ITypeDiscoveryService), new TypeDiscoveryService()); serviceContainer.AddService(typeof(MemberRelationshipService), new DefaultMemberRelationshipService()); - serviceContainer.AddService(typeof(ProjectResourceService), new ProjectResourceService(ParserService.GetParseInformation(this.DesignerCodeFile.FileName).CompilationUnit.ProjectContent)); + serviceContainer.AddService(typeof(ProjectResourceService), CreateProjectResourceService()); // Provide the ImageResourceEditor for all Image and Icon properties this.addedTypeDescriptionProviders.Add(typeof(Image), TypeDescriptor.AddAttributes(typeof(Image), new EditorAttribute(typeof(ImageResourceEditor), typeof(System.Drawing.Design.UITypeEditor)))); @@ -329,6 +329,21 @@ namespace ICSharpCode.FormsDesigner LoggingService.Info("Form Designer: END INITIALIZE"); } + ProjectResourceService CreateProjectResourceService() + { + IProjectContent projectContent = GetProjectContentForFile(); + return new ProjectResourceService(projectContent); + } + + IProjectContent GetProjectContentForFile() + { + ParseInformation parseInfo = ParserService.GetParseInformation(this.DesignerCodeFile.FileName); + if (parseInfo != null) { + return parseInfo.CompilationUnit.ProjectContent; + } + return DefaultProjectContent.DummyProjectContent; + } + bool hasUnmergedChanges; void MakeDirty() diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs index 04389441a6..889eeea69c 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs @@ -264,6 +264,10 @@ namespace ICSharpCode.FormsDesigner.Services */ asm = Assembly.LoadFile(tempPath); MarkFileToDeleteOnReboot(tempPath); + } else if (e.Message.Contains("HRESULT: 0x80131019")) { + LoggingService.Debug(e.Message); + LoggingService.Debug("Attempting to load unverifiable assembly. Ignoring."); + return null; } else { throw; // don't ignore other load errors } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/ToolboxProvider.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/ToolboxProvider.cs index aff68b55ea..84db6cd3e7 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/ToolboxProvider.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/ToolboxProvider.cs @@ -218,6 +218,10 @@ namespace ICSharpCode.FormsDesigner static IProject FindProjectContainingType(string type) { IProject currentProject = ProjectService.CurrentProject; + if (currentProject == null) { + return null; + } + foreach (IProject project in ProjectService.OpenSolution.Projects) { if (project != currentProject) { IProjectContent projectContent = ParserService.GetProjectContent(project); diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs index e5d383273d..15a9e9c37c 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs @@ -300,7 +300,10 @@ namespace ICSharpCode.AvalonEdit.Editing if (textArea.Selection.IsEmpty && textArea.Options.CutCopyWholeLine) { DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); CopyWholeLine(textArea, currentLine); - textArea.Document.Remove(currentLine.Offset, currentLine.TotalLength); + ISegment[] segmentsToDelete = textArea.GetDeletableSegments(new SimpleSegment(currentLine.Offset, currentLine.TotalLength)); + for (int i = segmentsToDelete.Length - 1; i >= 0; i--) { + textArea.Document.Remove(segmentsToDelete[i]); + } } else { CopySelectedText(textArea); textArea.RemoveSelectedText(); diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj index 8484dd233b..7570f505b0 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj @@ -343,6 +343,7 @@ + diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/IBackgroundRenderer.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/IBackgroundRenderer.cs index f8728f0a3b..cb9d87243e 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/IBackgroundRenderer.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/IBackgroundRenderer.cs @@ -11,9 +11,6 @@ namespace ICSharpCode.AvalonEdit.Rendering /// You can use background renderers to draw non-interactive elements on the TextView /// without introducing new UIElements. /// - /// Background renderer will draw only if their associated known - /// layer chooses to draw them. For example, background renderers in the caret - /// layer will be invisible when the caret is hidden. public interface IBackgroundRenderer { /// diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ITextRunConstructionContext.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ITextRunConstructionContext.cs index 83a2184540..f0fd8d1be0 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ITextRunConstructionContext.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ITextRunConstructionContext.cs @@ -4,6 +4,7 @@ using System; using System.Windows.Media.TextFormatting; using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Utils; namespace ICSharpCode.AvalonEdit.Rendering { @@ -31,5 +32,16 @@ namespace ICSharpCode.AvalonEdit.Rendering /// Gets the global text run properties. /// TextRunProperties GlobalTextRunProperties { get; } + + /// + /// Gets a piece of text from the document. + /// + /// + /// This method is allowed to return a larger string than requested. + /// It does this by returning a that describes the requested segment within the returned string. + /// This method should be the preferred text access method in the text transformation pipeline, as it can avoid repeatedly allocating string instances + /// for text within the same line. + /// + StringSegment GetText(int offset, int length); } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs index 0040decd12..70d59358ae 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs @@ -2,16 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Diagnostics; using System.Text.RegularExpressions; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.TextFormatting; - -using ICSharpCode.AvalonEdit.Document; -using System.Windows.Navigation; +using ICSharpCode.AvalonEdit.Utils; namespace ICSharpCode.AvalonEdit.Rendering { @@ -68,8 +60,8 @@ namespace ICSharpCode.AvalonEdit.Rendering Match GetMatch(int startOffset) { int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset; - string relevantText = CurrentContext.Document.GetText(startOffset, endOffset - startOffset); - return linkRegex.Match(relevantText); + StringSegment relevantText = CurrentContext.GetText(startOffset, endOffset - startOffset); + return linkRegex.Match(relevantText.Text, relevantText.Offset, relevantText.Count); } /// diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs index 3d26e7c9b9..4ff5def317 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs @@ -60,10 +60,11 @@ namespace ICSharpCode.AvalonEdit.Rendering public override int GetFirstInterestedOffset(int startOffset) { DocumentLine endLine = CurrentContext.VisualLine.LastDocumentLine; - string relevantText = CurrentContext.Document.GetText(startOffset, endLine.EndOffset - startOffset); + StringSegment relevantText = CurrentContext.GetText(startOffset, endLine.EndOffset - startOffset); - for (int i = 0; i < relevantText.Length; i++) { - char c = relevantText[i]; + int endPos = relevantText.Offset + relevantText.Count; + for (int i = relevantText.Offset; i < endPos; i++) { + char c = relevantText.Text[i]; switch (c) { case ' ': if (ShowSpaces) diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs index 47744a5942..2e4136b41a 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs @@ -53,7 +53,7 @@ namespace ICSharpCode.AvalonEdit.Rendering /// Gets the start offset of the VisualLine inside the document. /// This is equivalent to FirstDocumentLine.Offset. /// - public int StartOffset { + public int StartOffset { get { return FirstDocumentLine.Offset; } @@ -323,6 +323,12 @@ namespace ICSharpCode.AvalonEdit.Rendering public int GetVisualColumnFloor(Point point) { TextLine textLine = GetTextLineByVisualYPosition(point.Y); + if (point.X > textLine.WidthIncludingTrailingWhitespace) { + // GetCharacterHitFromDistance returns a hit with FirstCharacterIndex=last character inline + // and TrailingLength=1 when clicking behind the line, so the floor function needs to handle this case + // specially end return the line's end column instead. + return GetTextLineVisualStartColumn(textLine) + textLine.Length; + } CharacterHit ch = textLine.GetCharacterHitFromDistance(point.X); return ch.FirstCharacterIndex; } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineText.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineText.cs index 3cefe1e264..f5d7ae19ed 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineText.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineText.cs @@ -53,8 +53,8 @@ namespace ICSharpCode.AvalonEdit.Rendering throw new ArgumentNullException("context"); int relativeOffset = startVisualColumn - VisualColumn; - string text = context.Document.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset); - return new TextCharacters(text, 0, text.Length, this.TextRunProperties); + StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset); + return new TextCharacters(text.Text, text.Offset, text.Count, this.TextRunProperties); } /// @@ -71,8 +71,8 @@ namespace ICSharpCode.AvalonEdit.Rendering throw new ArgumentNullException("context"); int relativeOffset = visualColumnLimit - VisualColumn; - string text = context.Document.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset, relativeOffset); - CharacterBufferRange range = new CharacterBufferRange(text, 0, text.Length); + StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset, relativeOffset); + CharacterBufferRange range = new CharacterBufferRange(text.Text, text.Offset, text.Count); return new TextSpan(range.Length, new CultureSpecificCharacterBufferRange(this.TextRunProperties.CultureInfo, range)); } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineTextSource.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineTextSource.cs index eea016446f..375a09bf9e 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineTextSource.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineTextSource.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Windows.Media.TextFormatting; using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Utils; namespace ICSharpCode.AvalonEdit.Rendering { @@ -83,5 +84,19 @@ namespace ICSharpCode.AvalonEdit.Rendering { throw new NotSupportedException(); } + + string cachedString; + int cachedStringOffset; + + public StringSegment GetText(int offset, int length) + { + if (cachedString != null) { + if (offset >= cachedStringOffset && offset + length <= cachedStringOffset + cachedString.Length) { + return new StringSegment(cachedString, offset - cachedStringOffset, length); + } + } + cachedStringOffset = offset; + return new StringSegment(cachedString = this.Document.GetText(offset, length)); + } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/StringSegment.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/StringSegment.cs new file mode 100644 index 0000000000..8a39ea874f --- /dev/null +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/StringSegment.cs @@ -0,0 +1,107 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.AvalonEdit.Utils +{ + /// + /// Represents a string with a segment. + /// Similar to System.ArraySegment<T>, but for strings instead of arrays. + /// + public struct StringSegment : IEquatable + { + readonly string text; + readonly int offset; + readonly int count; + + /// + /// Creates a new StringSegment. + /// + public StringSegment(string text, int offset, int count) + { + if (text == null) + throw new ArgumentNullException("text"); + if (offset < 0 || offset > text.Length) + throw new ArgumentOutOfRangeException("offset"); + if (offset + count > text.Length) + throw new ArgumentOutOfRangeException("count"); + this.text = text; + this.offset = offset; + this.count = count; + } + + /// + /// Creates a new StringSegment. + /// + public StringSegment(string text) + { + if (text == null) + throw new ArgumentNullException("text"); + this.text = text; + this.offset = 0; + this.count = text.Length; + } + + /// + /// Gets the string used for this segment. + /// + public string Text { + get { return text; } + } + + /// + /// Gets the start offset of the segment with the text. + /// + public int Offset { + get { return offset; } + } + + /// + /// Gets the length of the segment. + /// + public int Count { + get { return count; } + } + + #region Equals and GetHashCode implementation + /// + public override bool Equals(object obj) + { + if (obj is StringSegment) + return Equals((StringSegment)obj); // use Equals method below + else + return false; + } + + /// + public bool Equals(StringSegment other) + { + // add comparisions for all members here + return object.ReferenceEquals(this.text, other.text) && offset == other.offset && count == other.count; + } + + /// + public override int GetHashCode() + { + return text.GetHashCode() ^ offset ^ count; + } + + /// + /// Equality operator. + /// + public static bool operator ==(StringSegment left, StringSegment right) + { + return left.Equals(right); + } + + /// + /// Inequality operator. + /// + public static bool operator !=(StringSegment left, StringSegment right) + { + return !left.Equals(right); + } + #endregion + } +} diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs index 01ed0ca426..d42b8f4e3e 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs @@ -559,7 +559,8 @@ namespace ICSharpCode.SharpDevelop.Gui this.Top = bounds.Top; this.Width = bounds.Width; this.Height = bounds.Height; - this.WindowState = memento.Get("WindowState", System.Windows.WindowState.Maximized); + lastNonMinimizedWindowState = memento.Get("WindowState", System.Windows.WindowState.Maximized); + this.WindowState = lastNonMinimizedWindowState; } protected override void OnClosing(CancelEventArgs e) diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs index a2905afd89..e903b9cb96 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs @@ -544,11 +544,10 @@ namespace ICSharpCode.SharpDevelop.Dom public override TextFinderMatch Find(string inputText, int startPosition) { int pos = inputText.IndexOf(searchText, startPosition); - if (pos >= 0) { + if (pos > 0) { return new TextFinderMatch(pos, searchText.Length, pos - 1); - } else { - return TextFinderMatch.Empty; } + return TextFinderMatch.Empty; } } #endregion diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/ICSharpCode.SharpDevelop.Dom.Tests.csproj b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/ICSharpCode.SharpDevelop.Dom.Tests.csproj index 6b5a6788de..ae4d307071 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/ICSharpCode.SharpDevelop.Dom.Tests.csproj +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/ICSharpCode.SharpDevelop.Dom.Tests.csproj @@ -52,8 +52,10 @@ + + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/IndexBeforeTextFinderTests.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/IndexBeforeTextFinderTests.cs new file mode 100644 index 0000000000..fafacb14c8 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/IndexBeforeTextFinderTests.cs @@ -0,0 +1,70 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; +using ICSharpCode.SharpDevelop.Dom.Tests.NUnitHelpers; +using NUnit.Framework; + +namespace ICSharpCode.SharpDevelop.Dom.Tests +{ + [TestFixture] + public class IndexBeforeTextFinderTests + { + TextFinder textFinder; + IndexBeforeTextFinderHelper helper; + + void CreateIndexBeforeTextFinderWithSearchTextOf(string searchText) + { + helper = new IndexBeforeTextFinderHelper(); + textFinder = helper.CreateIndexBeforeTextFinder(searchText); + } + + void AssertTextFindMatchesAreEqual(TextFinderMatch expectedMatch, TextFinderMatch actualMatch) + { + string expectedMatchAsString = GetTextFinderMatchAsString(expectedMatch); + string actualMatchAsString = GetTextFinderMatchAsString(actualMatch); + Assert.AreEqual(expectedMatchAsString, actualMatchAsString); + } + + string GetTextFinderMatchAsString(TextFinderMatch match) + { + return String.Format( + "Position: {0}, Length: {1}, ResolvePosition: {2}", + match.Position, + match.Length, + match.ResolvePosition); + } + + [Test] + public void Find_SearchingForSquareBracketCharacterAndInputTextHasNoSquareBracketCharacter_ReturnsEmptyTextFinderMatch() + { + CreateIndexBeforeTextFinderWithSearchTextOf("["); + TextFinderMatch match = textFinder.Find("abc", 0); + + AssertTextFindMatchesAreEqual(TextFinderMatch.Empty, match); + } + + [Test] + public void Find_SearchingForSquareBracketCharacterAndInputTextHasSquareBracketAtPositionOne_ReturnsTextFinderMatchForPositionOne() + { + CreateIndexBeforeTextFinderWithSearchTextOf("["); + TextFinderMatch match = textFinder.Find("a[0]", 0); + + TextFinderMatch expectedMatch = + new TextFinderMatch(position: 1, length: 1, resolvePosition: 0); + + AssertTextFindMatchesAreEqual(expectedMatch, match); + } + + [Test] + public void Find_SearchingForSquareBracketCharacterAndInputTextHasSquareBracketCharacterAtPositionZero_ReturnsEmptyTextFinderMatch() + { + CreateIndexBeforeTextFinderWithSearchTextOf("["); + TextFinderMatch match = textFinder.Find("[assembly: AssemblyCulture(\"\")]", 0); + + AssertTextFindMatchesAreEqual(TextFinderMatch.Empty, match); + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/NUnitHelpers/IndexBeforeTextFinderHelper.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/NUnitHelpers/IndexBeforeTextFinderHelper.cs new file mode 100644 index 0000000000..e7e966c4fc --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/NUnitHelpers/IndexBeforeTextFinderHelper.cs @@ -0,0 +1,21 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Dom.Refactoring; + +namespace ICSharpCode.SharpDevelop.Dom.Tests.NUnitHelpers +{ + public class IndexBeforeTextFinderHelper : LanguageProperties + { + public IndexBeforeTextFinderHelper() + : base(StringComparer.Ordinal) + { + } + + public TextFinder CreateIndexBeforeTextFinder(string searchText) + { + return new IndexBeforeTextFinder(searchText); + } + } +}