Skip to content

Commit f107b55

Browse files
authored
Merge pull request #3398 from bclothier/next
TokenExtensions hotfix
2 parents 3a210be + dabff17 commit f107b55

File tree

2 files changed

+107
-4
lines changed

2 files changed

+107
-4
lines changed

Rubberduck.Parsing/TokenExtensions.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ public static class TokenExtensions
1515
/// <returns>Zero-based column position</returns>
1616
public static int EndColumn(this IToken token)
1717
{
18-
if (token.Text.Contains(Environment.NewLine))
18+
if (token.Text == Environment.NewLine)
1919
{
20-
var splitStrings = token.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
20+
return token.Column;
21+
}
22+
else if (token.Text.Contains(Environment.NewLine))
23+
{
24+
var splitStrings = token.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
2125
var lastOccupiedLine = splitStrings[splitStrings.Length - 1];
2226

2327
return lastOccupiedLine.Length;
@@ -37,9 +41,9 @@ public static int EndColumn(this IToken token)
3741
/// <returns>One-based line position</returns>
3842
public static int EndLine(this IToken token)
3943
{
40-
if (token.Text.Contains(Environment.NewLine))
44+
if (token.Text != Environment.NewLine && token.Text.Contains(Environment.NewLine))
4145
{
42-
var splitStrings = token.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
46+
var splitStrings = token.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
4347

4448
return token.Line + (splitStrings.Length - 1);
4549
}

RubberduckTests/Grammar/SelectionExtensionsTests.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.VisualStudio.TestTools.UnitTesting;
33
using Rubberduck.Parsing;
44
using Rubberduck.Parsing.Grammar;
5+
using Rubberduck.Parsing.Symbols;
56
using static Rubberduck.Parsing.Grammar.VBAParser;
67
using Rubberduck.VBEditor;
78
using RubberduckTests.Mocks;
@@ -637,5 +638,103 @@ End If
637638
Assert.IsFalse(selection.Contains(contexts.ElementAt(1))); // first outer if block
638639
Assert.IsTrue(selection.Contains(contexts.ElementAt(2))); // second outer If block
639640
}
641+
642+
[TestMethod]
643+
[TestCategory("Grammar")]
644+
[TestCategory("Selection")]
645+
public void GivenOnlyBlankLines_EndColumn_Works()
646+
{
647+
const string inputCode = @"
648+
649+
650+
651+
";
652+
653+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component);
654+
var pane = component.CodeModule.CodePane;
655+
var state = MockParser.CreateAndParse(vbe.Object);
656+
657+
658+
var tree = (Antlr4.Runtime.ParserRuleContext)state.GetParseTree(new QualifiedModuleName(component));
659+
var startToken = tree.Start;
660+
var endToken = tree.Stop;
661+
662+
// Reminder: token columns are zero-based but lines are one-based
663+
Assert.IsTrue(startToken.EndColumn() == 0);
664+
Assert.IsTrue(endToken.EndColumn() == 0);
665+
}
666+
667+
[TestMethod]
668+
[TestCategory("Grammar")]
669+
[TestCategory("Selection")]
670+
public void GivenOnlyBlankLines_EndLine_Works()
671+
{
672+
const string inputCode = @"
673+
674+
675+
676+
";
677+
678+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component);
679+
var pane = component.CodeModule.CodePane;
680+
var state = MockParser.CreateAndParse(vbe.Object);
681+
682+
683+
var tree = (Antlr4.Runtime.ParserRuleContext)state.GetParseTree(new QualifiedModuleName(component));
684+
var startToken = tree.Start;
685+
var endToken = tree.Stop;
686+
687+
// Reminder: token columns are zero-based but lines are one-based
688+
Assert.IsTrue(startToken.EndLine() == 1);
689+
Assert.IsTrue(endToken.EndLine() == 4);
690+
}
691+
692+
[TestMethod]
693+
[TestCategory("Grammar")]
694+
[TestCategory("Selection")]
695+
public void GivenBlankLinesWithLeadingSpaces_EndColumn_Works()
696+
{
697+
const string inputCode = @"
698+
699+
700+
";
701+
702+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component);
703+
var pane = component.CodeModule.CodePane;
704+
var state = MockParser.CreateAndParse(vbe.Object);
705+
706+
707+
var tree = (Antlr4.Runtime.ParserRuleContext)state.GetParseTree(new QualifiedModuleName(component));
708+
var startToken = tree.Start;
709+
var endToken = tree.Stop;
710+
711+
// Reminder: token columns are zero-based but lines are one-based
712+
Assert.IsTrue(startToken.EndColumn() == 0);
713+
Assert.IsTrue(endToken.EndColumn() == 3);
714+
}
715+
716+
[TestMethod]
717+
[TestCategory("Grammar")]
718+
[TestCategory("Selection")]
719+
public void GivenBlankLinesWithLeadingSpaces_EndLine_Works()
720+
{
721+
const string inputCode = @"
722+
723+
724+
";
725+
726+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component);
727+
var pane = component.CodeModule.CodePane;
728+
var state = MockParser.CreateAndParse(vbe.Object);
729+
730+
731+
var tree = (Antlr4.Runtime.ParserRuleContext)state.GetParseTree(new QualifiedModuleName(component));
732+
var startToken = tree.Start;
733+
var endToken = tree.Stop;
734+
735+
// Reminder: token columns are zero-based but lines are one-based
736+
Assert.IsTrue(startToken.EndLine() == 1);
737+
Assert.IsTrue(endToken.EndLine() == 3);
738+
}
640739
}
641740
}

0 commit comments

Comments
 (0)