File: NamingStyle.WordSpanEnumerator.cs
Web Access
Project: ..\..\..\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.Text;
 
namespace Microsoft.CodeAnalysis.NamingStyles
{
    internal partial record struct NamingStyle
    {
        private struct WordSpanEnumerator
        {
            private readonly string _name;
            private readonly TextSpan _nameSpan;
            private readonly string _wordSeparator;
 
            public WordSpanEnumerator(string name, TextSpan nameSpan, string wordSeparator)
            {
                Debug.Assert(nameSpan.Length > 0);
                _name = name;
                _nameSpan = nameSpan;
                _wordSeparator = wordSeparator;
                Current = new TextSpan(nameSpan.Start, 0);
            }
 
            public TextSpan Current { get; private set; }
 
            public bool MoveNext()
            {
                if (_wordSeparator == "")
                {
                    // No separator.  So only ever return a single word
                    if (Current.Length == 0)
                    {
                        Current = _nameSpan;
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
 
                while (true)
                {
                    var nextWordSeparator = _name.IndexOf(_wordSeparator, Current.End);
                    if (nextWordSeparator == Current.End)
                    {
                        // We're right at the word separator.  Skip it and continue searching.
                        Current = new TextSpan(Current.End + _wordSeparator.Length, 0);
                        continue;
                    }
 
                    // If didn't find a word separator, it's as if the next word separator is at the end of name span.
                    if (nextWordSeparator < 0)
                    {
                        nextWordSeparator = _nameSpan.End;
                    }
 
                    // If we've walked past the _nameSpan just immediately stop.  There are no more words to return.
                    if (Current.End > _nameSpan.End)
                    {
                        return false;
                    }
 
                    // found a separator in front of us.  Note: it may be in our suffix portion.  
                    // So use the min of the separator position and our end position.
                    Current = TextSpan.FromBounds(Current.End, Math.Min(_nameSpan.End, nextWordSeparator));
                    break;
                }
 
                return Current.Length > 0 && Current.End <= _nameSpan.End;
            }
        }
    }
}