Skip to content

Commit 24a83ed

Browse files
author
Kapil Borle
committed
Update EditableText to use TextLines class
1 parent 15d6741 commit 24a83ed

1 file changed

Lines changed: 28 additions & 25 deletions

File tree

Engine/EditableText.cs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer
1313
/// </summary>
1414
public class EditableText
1515
{
16+
private TextLines lines { get; set; }
17+
1618
/// <summary>
1719
/// The text that is available for editing.
1820
/// </summary>
19-
public string Text { get; private set; }
21+
public string Text { get { return String.Join(NewLine, lines); } }
2022

2123
/// <summary>
2224
/// The lines in the Text.
2325
/// </summary>
24-
public string[] Lines { get; private set; }
26+
public string[] Lines { get { return lines.ToArray(); } }
2527

2628
/// <summary>
2729
/// The new line character in the Text.
@@ -39,12 +41,11 @@ public EditableText(string text)
3941
throw new ArgumentNullException(nameof(text));
4042
}
4143

42-
this.Text = text;
43-
Lines = this.Text.GetLines().ToArray();
44-
NewLine = GetNewLineCharacters();
44+
string[] lines;
45+
NewLine = GetNewLineCharacters(text, out lines);
46+
this.lines = new TextLines(lines);
4547
}
4648

47-
// TODO replace apply edit with an optimized version of this.
4849
/// <summary>
4950
/// Apply edits defined by a TextEdit object to Text.
5051
/// </summary>
@@ -55,24 +56,23 @@ public EditableText ApplyEdit(TextEdit textEdit)
5556
ValidateTextEdit(textEdit);
5657

5758
var editLines = textEdit.Lines;
58-
var Lines = new TextLines(this.Lines);
5959

6060
// Get the first fragment of the first line
6161
string firstLineFragment =
62-
Lines[textEdit.StartLineNumber - 1]
62+
lines[textEdit.StartLineNumber - 1]
6363
.Substring(0, textEdit.StartColumnNumber - 1);
6464

6565
// Get the last fragment of the last line
66-
string endLine = Lines[textEdit.EndLineNumber - 1];
66+
string endLine = lines[textEdit.EndLineNumber - 1];
6767
string lastLineFragment =
6868
endLine.Substring(
6969
textEdit.EndColumnNumber - 1,
70-
Lines[textEdit.EndLineNumber - 1].Length - textEdit.EndColumnNumber + 1);
70+
lines[textEdit.EndLineNumber - 1].Length - textEdit.EndColumnNumber + 1);
7171

7272
// Remove the old lines
7373
for (int i = 0; i <= textEdit.EndLineNumber - textEdit.StartLineNumber; i++)
7474
{
75-
Lines.RemoveAt(textEdit.StartLineNumber - 1);
75+
lines.RemoveAt(textEdit.StartLineNumber - 1);
7676
}
7777

7878
// Build and insert the new lines
@@ -95,11 +95,11 @@ public EditableText ApplyEdit(TextEdit textEdit)
9595
finalLine = finalLine + lastLineFragment;
9696
}
9797

98-
Lines.Insert(currentLineNumber - 1, finalLine);
98+
lines.Insert(currentLineNumber - 1, finalLine);
9999
currentLineNumber++;
100100
}
101101

102-
return new EditableText(String.Join(NewLine, Lines));
102+
return new EditableText(String.Join(NewLine, lines));
103103
}
104104

105105
// TODO Add a method that takes multiple edits, checks if they are unique and applies them.
@@ -154,33 +154,35 @@ private int GetOffset(int lineNumber, int columnNumber)
154154
return offset + zeroBasedColumnNumber;
155155
}
156156

157-
private string GetNewLineCharacters()
157+
private static string GetNewLineCharacters(string text, out string[] lines)
158158
{
159-
if (Lines.Length == 1)
159+
int numNewLineChars = GetNumNewLineCharacters(text, out lines);
160+
if (lines.Length == 1)
160161
{
161162
return Environment.NewLine;
162163
}
163164

164-
return Text.Substring(Lines[0].Length, GetNumNewLineCharacters());
165+
return text.Substring(lines[0].Length, numNewLineChars);
165166
}
166167

167-
private int GetNumNewLineCharacters()
168+
private static int GetNumNewLineCharacters(string text, out string[] lines)
168169
{
169-
if (Lines.Length == 1)
170+
lines = text.GetLines().ToArray();
171+
if (lines.Length == 1)
170172
{
171173
return Environment.NewLine.Length;
172174
}
173175

174-
var charsInLines = Lines.Sum(line => line.Length);
175-
var numCharDiff = Text.Length - charsInLines;
176-
int remainder = numCharDiff % (Lines.Length - 1);
176+
var charsInLines = lines.Sum(line => line.Length);
177+
var numCharDiff = text.Length - charsInLines;
178+
int remainder = numCharDiff % (lines.Length - 1);
177179
if (remainder != 0)
178180
{
179181
// TODO localize
180-
throw new ArgumentException("Cannot determine line endings as the text probably contain mixed line endings.", nameof(Text));
182+
throw new ArgumentException("Cannot determine line endings as the text probably contain mixed line endings.", nameof(text));
181183
}
182184

183-
return numCharDiff / (Lines.Length - 1);
185+
return numCharDiff / (lines.Length - 1);
184186
}
185187

186188
private class TextLines : IList<String>
@@ -234,6 +236,7 @@ private LinkedListNode<String> GetNodeAt(int index)
234236
{
235237
if (count == index)
236238
{
239+
SetLastAccessed(index, node);
237240
return node;
238241
}
239242

@@ -260,10 +263,10 @@ private void GetClosestReference(
260263
var delta = index - lastAccessedIndex;
261264
var deltaAbs = Math.Abs(delta);
262265

263-
// lastAccessedIndex is closer to index than 0
266+
// lastAccessedIndex is closer to index than that to 0
264267
if (IsLastAccessedValid() && deltaAbs < index)
265268
{
266-
// lastAccessedIndex is closer to index than Count - 1
269+
// lastAccessedIndex is closer to index than to (Count - 1)
267270
if (deltaAbs < (Count - 1 - index))
268271
{
269272
refNode = lastAccessedNode;

0 commit comments

Comments
 (0)