Skip to content

Commit 6b7f8fc

Browse files
committed
Fix bracket escaping in end of line comments. Closes #2696
1 parent a9a5336 commit 6b7f8fc

File tree

3 files changed

+58
-25
lines changed

3 files changed

+58
-25
lines changed

Rubberduck.SmartIndenter/AbsoluteCodeLine.cs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ namespace Rubberduck.SmartIndenter
1010
internal class AbsoluteCodeLine
1111
{
1212
private const string StupidLineEnding = ": _";
13-
private static readonly Regex StringReplaceRegex = new Regex(StringLiteralAndBracketEscaper.StringPlaceholder.ToString(CultureInfo.InvariantCulture));
14-
private static readonly Regex BracketReplaceRegex = new Regex(StringLiteralAndBracketEscaper.BracketPlaceholder.ToString(CultureInfo.InvariantCulture));
1513
private static readonly Regex LineNumberRegex = new Regex(@"^(?<number>(-?\d+)|(&H[0-9A-F]{1,8}))\s+(?<code>.*)", RegexOptions.ExplicitCapture);
1614
private static readonly Regex EndOfLineCommentRegex = new Regex(@"^(?!(Rem\s)|('))(?<code>[^']*)(\s(?<comment>'.*))$", RegexOptions.ExplicitCapture);
1715
private static readonly Regex ProcedureStartRegex = new Regex(@"^(Public\s|Private\s|Friend\s)?(Static\s)?(Sub|Function|Property\s(Let|Get|Set))\s");
@@ -61,8 +59,8 @@ public AbsoluteCodeLine(string code, IIndenterSettings settings, AbsoluteCodeLin
6159
ExtractLineNumber();
6260
ExtractEndOfLineComment();
6361

64-
_code = Regex.Replace(_code, StringLiteralAndBracketEscaper.StringPlaceholder + "+", StringLiteralAndBracketEscaper.StringPlaceholder.ToString(CultureInfo.InvariantCulture));
65-
_code = Regex.Replace(_code, StringLiteralAndBracketEscaper.BracketPlaceholder + "+", StringLiteralAndBracketEscaper.BracketPlaceholder.ToString(CultureInfo.InvariantCulture)).Trim();
62+
//_code = Regex.Replace(_code, StringLiteralAndBracketEscaper.StringPlaceholder + "+", StringLiteralAndBracketEscaper.StringPlaceholder.ToString(CultureInfo.InvariantCulture));
63+
//_code = Regex.Replace(_code, StringLiteralAndBracketEscaper.BracketPlaceholder + "+", StringLiteralAndBracketEscaper.BracketPlaceholder.ToString(CultureInfo.InvariantCulture)).Trim();
6664
_segments = _code.Split(new[] { ": " }, StringSplitOptions.None);
6765
}
6866

@@ -267,38 +265,29 @@ public string Indent(int indents, bool atProcStart, bool absolute = false)
267265
}
268266

269267
var code = string.Join(": ", _segments);
270-
if (_escaper.EscapedStrings.Any())
271-
{
272-
code = _escaper.EscapedStrings.Aggregate(code, (current, literal) => StringReplaceRegex.Replace(current, literal, 1));
273-
}
274-
if (_escaper.EscapedBrackets.Any())
275-
{
276-
code = _escaper.EscapedBrackets.Aggregate(code, (current, expr) => BracketReplaceRegex.Replace(current, expr, 1));
277-
}
278-
279268
code = string.Join(string.Empty, number, new string(' ', gap), code);
280269
if (string.IsNullOrEmpty(EndOfLineComment))
281270
{
282-
return code + (_stupidLineEnding ? StupidLineEnding : string.Empty);
271+
return _escaper.UnescapeIndented(code + (_stupidLineEnding ? StupidLineEnding : string.Empty));
283272
}
284273

285274
var position = Original.LastIndexOf(EndOfLineComment, StringComparison.Ordinal);
286275
switch (_settings.EndOfLineCommentStyle)
287276
{
288277
case EndOfLineCommentStyle.Absolute:
289-
return string.Format("{0}{1}{2}{3}", code, new string(' ', Math.Max(position - code.Length, 1)),
290-
EndOfLineComment, _stupidLineEnding ? StupidLineEnding : string.Empty);
278+
return _escaper.UnescapeIndented(string.Format("{0}{1}{2}{3}", code, new string(' ', Math.Max(position - code.Length, 1)),
279+
EndOfLineComment, _stupidLineEnding ? StupidLineEnding : string.Empty));
291280
case EndOfLineCommentStyle.SameGap:
292281
var uncommented = Original.Substring(0, position - 1);
293-
return string.Format("{0}{1}{2}{3}", code, new string(' ', uncommented.Length - uncommented.TrimEnd().Length + 1),
294-
EndOfLineComment, _stupidLineEnding ? StupidLineEnding : string.Empty);
282+
return _escaper.UnescapeIndented(string.Format("{0}{1}{2}{3}", code, new string(' ', uncommented.Length - uncommented.TrimEnd().Length + 1),
283+
EndOfLineComment, _stupidLineEnding ? StupidLineEnding : string.Empty));
295284
case EndOfLineCommentStyle.StandardGap:
296-
return string.Format("{0}{1}{2}{3}", code, new string(' ', _settings.IndentSpaces * 2), EndOfLineComment,
297-
_stupidLineEnding ? StupidLineEnding : string.Empty);
285+
return _escaper.UnescapeIndented(string.Format("{0}{1}{2}{3}", code, new string(' ', _settings.IndentSpaces * 2), EndOfLineComment,
286+
_stupidLineEnding ? StupidLineEnding : string.Empty));
298287
case EndOfLineCommentStyle.AlignInColumn:
299288
var align = _settings.EndOfLineCommentColumnSpaceAlignment - code.Length;
300-
return string.Format("{0}{1}{2}{3}", code, new string(' ', Math.Max(align - 1, 1)), EndOfLineComment,
301-
_stupidLineEnding ? StupidLineEnding : string.Empty);
289+
return _escaper.UnescapeIndented(string.Format("{0}{1}{2}{3}", code, new string(' ', Math.Max(align - 1, 1)), EndOfLineComment,
290+
_stupidLineEnding ? StupidLineEnding : string.Empty));
302291
default:
303292
throw new InvalidEnumArgumentException();
304293
}

Rubberduck.SmartIndenter/StringLiteralAndBracketEscaper.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
using System.Collections.Generic;
2+
using System.Globalization;
23
using System.Linq;
4+
using System.Text.RegularExpressions;
35

46
namespace Rubberduck.SmartIndenter
57
{
68
internal class StringLiteralAndBracketEscaper
79
{
810
public const char StringPlaceholder = '\a';
9-
public const char BracketPlaceholder = '\x2';
11+
public const char BracketPlaceholder = '\x02';
12+
13+
private static readonly Regex StringReplaceRegex = new Regex("\a+");
14+
private static readonly Regex BracketReplaceRegex = new Regex("\x02+");
1015

1116
private readonly List<string> _strings = new List<string>();
1217
private readonly List<string> _brackets = new List<string>();
@@ -18,6 +23,20 @@ internal class StringLiteralAndBracketEscaper
1823
public IEnumerable<string> EscapedStrings { get { return _strings; } }
1924
public IEnumerable<string> EscapedBrackets { get { return _brackets; } }
2025

26+
public string UnescapeIndented(string indented)
27+
{
28+
var code = indented;
29+
if (_strings.Any())
30+
{
31+
code = _strings.Aggregate(code, (current, literal) => StringReplaceRegex.Replace(current, literal, 1));
32+
}
33+
if (_brackets.Any())
34+
{
35+
code = _brackets.Aggregate(code, (current, expr) => BracketReplaceRegex.Replace(current, expr, 1));
36+
}
37+
return code;
38+
}
39+
2140
public StringLiteralAndBracketEscaper(string code)
2241
{
2342
_unescaped = code;
@@ -63,8 +82,8 @@ public StringLiteralAndBracketEscaper(string code)
6382
continue;
6483
}
6584
bracketed = false;
66-
_brackets.Add(new string(chars.Skip(brkpos).Take(c - brkpos).ToArray()));
67-
for (var e = brkpos; e < c; e++)
85+
_brackets.Add(new string(chars.Skip(brkpos).Take(c - brkpos + 1).ToArray()));
86+
for (var e = brkpos; e <= c; e++)
6887
{
6988
chars[e] = BracketPlaceholder;
7089
}

RubberduckTests/SmartIndenter/MiscAndCornerCaseTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,31 @@ public void BracketedIdentifiersWork()
746746
Assert.IsTrue(expected.SequenceEqual(actual));
747747
}
748748

749+
//https://github.com/rubberduck-vba/Rubberduck/issues/2696
750+
[TestMethod]
751+
// Broken in VB6 SmartIndenter.
752+
[TestCategory("Indenter")]
753+
public void BracketsInEndOfLineCommentsWork()
754+
{
755+
var code = new[]
756+
{
757+
"Public Sub Test()",
758+
"Debug.Print \"foo\" \'update [foo].[bar] in the frob.",
759+
"End Sub"
760+
};
761+
762+
var expected = new[]
763+
{
764+
"Public Sub Test()",
765+
" Debug.Print \"foo\" 'update [foo].[bar] in the frob.",
766+
"End Sub"
767+
};
768+
769+
var indenter = new Indenter(null, () => IndenterSettingsTests.GetMockIndenterSettings());
770+
var actual = indenter.Indent(code);
771+
Assert.IsTrue(expected.SequenceEqual(actual));
772+
}
773+
749774
//https://github.com/rubberduck-vba/Rubberduck/issues/2604
750775
[TestMethod]
751776
[TestCategory("Indenter")]

0 commit comments

Comments
 (0)