Skip to content

Commit 8455e11

Browse files
authored
Merge pull request #4433 from comintern/indenter
Make string escapes consistant with brackets, fixes indenter bug
2 parents dd0c31b + 6142332 commit 8455e11

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

Rubberduck.SmartIndenter/StringLiteralAndBracketEscaper.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.Linq;
35
using System.Text.RegularExpressions;
46

@@ -9,9 +11,6 @@ internal class StringLiteralAndBracketEscaper
911
public const char StringPlaceholder = '\a';
1012
public const char BracketPlaceholder = '\x02';
1113

12-
private static readonly Regex StringReplaceRegex = new Regex("\a+", RegexOptions.IgnoreCase);
13-
private static readonly Regex BracketReplaceRegex = new Regex("\x02+", RegexOptions.IgnoreCase);
14-
1514
private readonly List<string> _strings = new List<string>();
1615
private readonly List<string> _brackets = new List<string>();
1716

@@ -24,16 +23,20 @@ internal class StringLiteralAndBracketEscaper
2423

2524
public string UnescapeIndented(string indented)
2625
{
27-
var code = indented;
28-
if (_strings.Any())
29-
{
30-
code = _strings.Aggregate(code, (current, literal) => StringReplaceRegex.Replace(current, literal, 1));
31-
}
32-
if (_brackets.Any())
26+
27+
var code = ReplaceEscapedItems(indented, StringPlaceholder, EscapedStrings);
28+
return ReplaceEscapedItems(code, BracketPlaceholder, EscapedBrackets);
29+
}
30+
31+
private string ReplaceEscapedItems(string code, char placehoder, IEnumerable<string> replacements)
32+
{
33+
var output = code;
34+
foreach (var item in replacements)
3335
{
34-
code = _brackets.Aggregate(code, (current, expr) => BracketReplaceRegex.Replace(current, expr, 1));
36+
var pos = output.IndexOf(new string(placehoder, item.Length), StringComparison.Ordinal);
37+
output = output.Substring(0, pos) + item + output.Substring(pos + item.Length);
3538
}
36-
return code;
39+
return output;
3740
}
3841

3942
public StringLiteralAndBracketEscaper(string code)
@@ -56,13 +59,13 @@ public StringLiteralAndBracketEscaper(string code)
5659
quoted = true;
5760
continue;
5861
}
59-
if (c + 1 < chars.Length && chars[c] == '"')
62+
if (c + 1 < chars.Length && chars[c + 1] == '"')
6063
{
6164
c++;
6265
}
6366
quoted = false;
64-
_strings.Add(new string(chars.Skip(strpos).Take(c - strpos).ToArray()));
65-
for (var e = strpos; e < c; e++)
67+
_strings.Add(OriginalString.Substring(strpos, c - strpos + 1));
68+
for (var e = strpos; e <= c; e++)
6669
{
6770
chars[e] = StringPlaceholder;
6871
}
@@ -81,7 +84,7 @@ public StringLiteralAndBracketEscaper(string code)
8184
continue;
8285
}
8386
bracketed = false;
84-
_brackets.Add(new string(chars.Skip(brkpos).Take(c - brkpos + 1).ToArray()));
87+
_brackets.Add(OriginalString.Substring(brkpos, c - brkpos + 1));
8588
for (var e = brkpos; e <= c; e++)
8689
{
8790
chars[e] = BracketPlaceholder;

RubberduckTests/SmartIndenter/MiscAndCornerCaseTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,5 +966,28 @@ public void LineNumbersInsideContinuationsWork()
966966
var actual = indenter.Indent(code);
967967
Assert.IsTrue(expected.SequenceEqual(actual));
968968
}
969+
970+
[Test]
971+
[Category("Indenter")]
972+
public void ReplacementPatternsInStringLiteralWorks()
973+
{
974+
var code = new[]
975+
{
976+
"Public Sub Test()",
977+
"Debug.Print \"a*${test}b\"",
978+
"End Sub"
979+
};
980+
981+
var expected = new[]
982+
{
983+
"Public Sub Test()",
984+
" Debug.Print \"a*${test}b\"",
985+
"End Sub"
986+
};
987+
988+
var indenter = new Indenter(null, () => IndenterSettingsTests.GetMockIndenterSettings());
989+
var actual = indenter.Indent(code);
990+
Assert.IsTrue(expected.SequenceEqual(actual));
991+
}
969992
}
970993
}

0 commit comments

Comments
 (0)