Welcome to mirror list, hosted at ThFree Co, Russian Federation.

TokenizedStringList.cs « DifferenceAlgorithm « Impl « Text « src - github.com/microsoft/vs-editor-api.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f7afc1c7ce32dfb579aa3bb3ef28411242e55c09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//
//  Copyright (c) Microsoft Corporation. All rights reserved.
//  Licensed under the MIT License. See License.txt in the project root for license information.
//
// This file contain implementations details that are subject to change without notice.
// Use at your own risk.
//
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Utilities;

namespace Microsoft.VisualStudio.Text.Differencing.Implementation
{
    internal interface ITokenizedStringListInternal : ITokenizedStringList
    {
        string OriginalSubstring(int startIndex, int length);
    }

    /// <summary>
    /// Tokenizes the string into abutting and non-overlapping segments.
    /// </summary>
    /// <remarks>
    /// This class implements IList so that it can be used with 
    /// <see cref="IDifferenceService" />, which finds the differences between two sequences represented
    /// as ILists.
    /// Most of the members of the IList interface are unimplemented. The only
    /// implemented methods are the array accessor getter (operator []), Count,
    /// and IsReadOnly.
    /// </remarks>
    internal abstract class TokenizedStringList : ITokenizedStringListInternal
    {
        protected List<Span> Tokens = new List<Span>();
        private readonly string original;
        private readonly SnapshotSpan originalSpan;

        /// <summary>
        /// Creates a tokenized string list from the original string.
        /// Any derived class must initialize the Tokens list in its own constructor.
        /// </summary>
        /// <param name="original">The original string.</param>
        protected TokenizedStringList(string original)
        {
            if (original == null)
                throw new ArgumentNullException("original");

            this.original = original;
        }

        protected TokenizedStringList(SnapshotSpan originalSpan)
        {
            this.originalSpan = originalSpan;
        }

        /// <summary>
        /// The original string that was tokenized.
        /// </summary>
        public string Original
        {
            get
            {
                // A call to GetText() here could be very expensive in memory. Be careful!
                return original ?? originalSpan.GetText();
            }
        }

        internal int OriginalLength
        {
            get
            {
                return (original != null) ? original.Length : originalSpan.Length;
            }
        }

        public string OriginalSubstring(int startIndex, int length)
        {
            if (original != null)
            {
                return original.Substring(startIndex, length);
            }
            else
            {
                ITextSnapshot snap = originalSpan.Snapshot;
                return snap.GetText(originalSpan.Start.Position + startIndex, length);
            }
        }

        /// <summary>
        /// Maps the index of an element to its span in the original list.
        /// </summary>
        /// <param name="index">The index of the element in the element list.</param>
        /// <returns>The span of the element.</returns>
        /// <exception cref="ArgumentOutOfRangeException">The specified index is either negative or exceeds the list's Count property.</exception>
        /// <remarks>This method returns a zero-length span at the end of the string if index
        /// is equal to the list's Count property.</remarks>
        public Span GetElementInOriginal(int index)
        {
            //Pure support for backward compatibility
            if (index == this.Count)
            {
                return new Span(this.OriginalLength, 0);
            }

            return this.Tokens[index];
        }

        /// <summary>
        /// Maps a span of elements in this list to the span in the original list.
        /// </summary>
        /// <param name="span">The span of elements in the elements list.</param>
        /// <returns>The span mapped onto the original list.</returns>
        public Span GetSpanInOriginal(Span span)
        {
            //Pure support for backward compatibility
            if (span.Start == this.Tokens.Count)
            {
                return new Span(this.OriginalLength, 0);
            }

            int start = this.Tokens[span.Start].Start;
            int end = (span.Length == 0) ? start : this.Tokens[span.End - 1].End;

            return Span.FromBounds(start, end);
        }

        /// <summary>
        /// Gets a string of the given element.
        /// </summary>
        /// <param name="index">The index into the list of elements.</param>
        /// <returns>The element, as a string.</returns>
        /// <remarks>The setter of this property throws a NotImplementedException.</remarks>
        public string this[int index]
        {
            get
            {
                // The out of range check will happen in GetElementInOriginal
                Span span = GetElementInOriginal(index);
                return this.OriginalSubstring(span.Start, span.Length);
            }
            set
            {
                throw new NotSupportedException();
            }
        }

        internal char CharacterAt(int offset)
        {
            return (original != null) ? original[offset] : originalSpan.Snapshot[originalSpan.Start.Position + offset];
        }

        /// <summary>
        /// The number of elements in the list.
        /// </summary>
        public int Count
        {
            get 
            { 
                return this.Tokens.Count; 
            }
        }

        /// <summary>
        /// Determines whether this list is read-only. It always returnes <c>true</c>.
        /// </summary>
        public bool IsReadOnly
        {
            get { return true; }
        }

#region Not Implemented
        /// <summary>
        /// Not implemented
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public int IndexOf(string item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        public void Insert(int index, string item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        /// <param name="index"></param>
        public void RemoveAt(int index)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        /// <param name="item"></param>
        public void Add(string item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        public void Clear()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        public bool Contains(string item)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        public void CopyTo(string[] array, int arrayIndex)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Not implemented.
        /// </summary>
        public bool Remove(string item)
        {
            throw new NotSupportedException();
        }

#endregion

#region IEnumerable<string> Members

        /// <summary>
        /// Gets the enumerator of type string.
        /// </summary>
        /// <returns>The enumerator of type string.</returns>
        public IEnumerator<string> GetEnumerator()
        {
            for (int i = 0; i < Count; i++)
                yield return this[i];
        }

#endregion

#region IEnumerable Members

        /// <summary>
        /// Gets the untyped enumerator.
        /// </summary>
        /// <returns>The untyped enumerator.</returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

#endregion
    }
}