@@ -58,11 +58,12 @@ private static void Parse(
5858
5959 // A stack of span starts along with their associated annotation name. [||] spans simply
6060 // have empty string for their annotation name.
61- var spanStartStack = new Stack < Tuple < int , string > > ( ) ;
61+ var spanStartStack = new Stack < ( int matchIndex , string name ) > ( ) ;
62+ var namedSpanStartStack = new Stack < ( int matchIndex , string name ) > ( ) ;
6263
6364 while ( true )
6465 {
65- var matches = new List < Tuple < int , string > > ( ) ;
66+ var matches = new List < ( int matchIndex , string name ) > ( ) ;
6667 AddMatch ( input , PositionString , currentIndexInInput , matches ) ;
6768 AddMatch ( input , SpanStartString , currentIndexInInput , matches ) ;
6869 AddMatch ( input , SpanEndString , currentIndexInInput , matches ) ;
@@ -71,7 +72,7 @@ private static void Parse(
7172 var namedSpanStartMatch = s_namedSpanStartRegex . Match ( input , currentIndexInInput ) ;
7273 if ( namedSpanStartMatch . Success )
7374 {
74- matches . Add ( Tuple . Create ( namedSpanStartMatch . Index , namedSpanStartMatch . Value ) ) ;
75+ matches . Add ( ( namedSpanStartMatch . Index , namedSpanStartMatch . Value ) ) ;
7576 }
7677
7778 if ( matches . Count == 0 )
@@ -80,10 +81,10 @@ private static void Parse(
8081 break ;
8182 }
8283
83- var orderedMatches = matches . OrderBy ( ( t1 , t2 ) => t1 . Item1 - t2 . Item1 ) . ToList ( ) ;
84+ var orderedMatches = matches . OrderBy ( ( t1 , t2 ) => t1 . matchIndex - t2 . matchIndex ) . ToList ( ) ;
8485 if ( orderedMatches . Count >= 2 &&
85- spanStartStack . Count > 0 &&
86- matches [ 0 ] . Item1 == matches [ 1 ] . Item1 - 1 )
86+ ( spanStartStack . Count > 0 || namedSpanStartStack . Count > 0 ) &&
87+ matches [ 0 ] . matchIndex == matches [ 1 ] . matchIndex - 1 )
8788 {
8889 // We have a slight ambiguity with cases like these:
8990 //
@@ -92,8 +93,8 @@ private static void Parse(
9293 // Is it starting a new match, or ending an existing match. As a workaround, we
9394 // special case these and consider it ending a match if we have something on the
9495 // stack already.
95- if ( ( matches [ 0 ] . Item2 == SpanStartString && matches [ 1 ] . Item2 == SpanEndString && spanStartStack . Peek ( ) . Item2 == string . Empty ) ||
96- ( matches [ 0 ] . Item2 == SpanStartString && matches [ 1 ] . Item2 == NamedSpanEndString && spanStartStack . Peek ( ) . Item2 != string . Empty ) )
96+ if ( ( matches [ 0 ] . name == SpanStartString && matches [ 1 ] . name == SpanEndString && ! spanStartStack . IsEmpty ( ) ) ||
97+ ( matches [ 0 ] . name == SpanStartString && matches [ 1 ] . name == NamedSpanEndString && ! namedSpanStartStack . IsEmpty ( ) ) )
9798 {
9899 orderedMatches . RemoveAt ( 0 ) ;
99100 }
@@ -102,8 +103,8 @@ private static void Parse(
102103 // Order the matches by their index
103104 var firstMatch = orderedMatches . First ( ) ;
104105
105- var matchIndexInInput = firstMatch . Item1 ;
106- var matchString = firstMatch . Item2 ;
106+ var matchIndexInInput = firstMatch . matchIndex ;
107+ var matchString = firstMatch . name ;
107108
108109 var matchIndexInOutput = matchIndexInInput - inputOutputOffset ;
109110 outputBuilder . Append ( input . Substring ( currentIndexInInput , matchIndexInInput - currentIndexInInput ) ) ;
@@ -123,7 +124,7 @@ private static void Parse(
123124 break ;
124125
125126 case SpanStartString :
126- spanStartStack . Push ( Tuple . Create ( matchIndexInOutput , string . Empty ) ) ;
127+ spanStartStack . Push ( ( matchIndexInOutput , string . Empty ) ) ;
127128 break ;
128129
129130 case SpanEndString :
@@ -132,31 +133,22 @@ private static void Parse(
132133 throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , SpanEndString , SpanStartString ) ) ;
133134 }
134135
135- if ( spanStartStack . Peek ( ) . Item2 . Length > 0 )
136- {
137- throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , NamedSpanStartString , NamedSpanEndString ) ) ;
138- }
139-
140136 PopSpan ( spanStartStack , tempSpans , matchIndexInOutput ) ;
141137 break ;
142138
143139 case NamedSpanStartString :
144140 var name = namedSpanStartMatch . Groups [ 1 ] . Value ;
145- spanStartStack . Push ( Tuple . Create ( matchIndexInOutput , name ) ) ;
141+ namedSpanStartStack . Push ( ( matchIndexInOutput , name ) ) ;
146142 break ;
147143
148144 case NamedSpanEndString :
149- if ( spanStartStack . Count == 0 )
145+ if ( namedSpanStartStack . Count == 0 )
150146 {
151147 throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , NamedSpanEndString , NamedSpanStartString ) ) ;
152148 }
153149
154- if ( spanStartStack . Peek ( ) . Item2 . Length == 0 )
155- {
156- throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , SpanStartString , SpanEndString ) ) ;
157- }
158150
159- PopSpan ( spanStartStack , tempSpans , matchIndexInOutput ) ;
151+ PopSpan ( namedSpanStartStack , tempSpans , matchIndexInOutput ) ;
160152 break ;
161153
162154 default :
@@ -169,6 +161,11 @@ private static void Parse(
169161 throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , SpanStartString , SpanEndString ) ) ;
170162 }
171163
164+ if ( namedSpanStartStack . Count > 0 )
165+ {
166+ throw new ArgumentException ( string . Format ( "Saw {0} without matching {1}" , NamedSpanEndString , NamedSpanEndString ) ) ;
167+ }
168+
172169 // Append the remainder of the string.
173170 outputBuilder . Append ( input . Substring ( currentIndexInInput ) ) ;
174171 output = outputBuilder . ToString ( ) ;
@@ -187,22 +184,22 @@ private static V GetOrAdd<K, V>(IDictionary<K, V> dictionary, K key, Func<K, V>
187184 }
188185
189186 private static void PopSpan (
190- Stack < Tuple < int , string > > spanStartStack ,
187+ Stack < ( int matchIndex , string name ) > spanStartStack ,
191188 IDictionary < string , ArrayBuilder < TextSpan > > spans ,
192189 int finalIndex )
193190 {
194- var spanStartTuple = spanStartStack . Pop ( ) ;
191+ var ( matchIndex , name ) = spanStartStack . Pop ( ) ;
195192
196- var span = TextSpan . FromBounds ( spanStartTuple . Item1 , finalIndex ) ;
197- GetOrAdd ( spans , spanStartTuple . Item2 , _ => ArrayBuilder < TextSpan > . GetInstance ( ) ) . Add ( span ) ;
193+ var span = TextSpan . FromBounds ( matchIndex , finalIndex ) ;
194+ GetOrAdd ( spans , name , _ => ArrayBuilder < TextSpan > . GetInstance ( ) ) . Add ( span ) ;
198195 }
199196
200- private static void AddMatch ( string input , string value , int currentIndex , List < Tuple < int , string > > matches )
197+ private static void AddMatch ( string input , string value , int currentIndex , List < ( int , string ) > matches )
201198 {
202199 var index = input . IndexOf ( value , currentIndex , StringComparison . Ordinal ) ;
203200 if ( index >= 0 )
204201 {
205- matches . Add ( Tuple . Create ( index , value ) ) ;
202+ matches . Add ( ( index , value ) ) ;
206203 }
207204 }
208205
0 commit comments