Skip to content

Commit

Permalink
Fix calculation for slot containing offset
Browse files Browse the repository at this point in the history
Fixes issue dotnet#605

Add logic to not return zero-length nodes, since they never contain
their offset.
  • Loading branch information
mattwar committed Feb 20, 2015
1 parent 7b474cb commit 3799cae
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
Expand Up @@ -53,7 +53,19 @@ public override int FindSlotIndexContainingOffset(int offset)
{
Debug.Assert(offset >= 0 && offset < FullWidth);
int idx = _childOffsets.BinarySearch(offset);
return idx >= 0 ? idx : (~idx - 1);

if (idx < 0)
{
idx = (~idx - 1);
}

// skip zero-length nodes (they won't ever contain the offset)
while (idx < _childOffsets.Length - 1 && _childOffsets[idx] == _childOffsets[idx + 1])
{
idx++;
}

return idx;
}

private static int[] CalculateOffsets(ArrayElement<CSharpSyntaxNode>[] children)
Expand Down
38 changes: 38 additions & 0 deletions src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNodeTests.cs
Expand Up @@ -481,6 +481,44 @@ public void TestFindToken()
Assert.Equal(SyntaxKind.IfKeyword, token.Kind());
}

[Fact]
public void TestFindTokenInLargeList()
{
var identifier = SyntaxFactory.Identifier("x");
var missingIdentifier = SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken);
var name = SyntaxFactory.IdentifierName(identifier);
var missingName = SyntaxFactory.IdentifierName(missingIdentifier);
var comma = SyntaxFactory.Token(SyntaxKind.CommaToken);
var missingComma = SyntaxFactory.MissingToken(SyntaxKind.CommaToken);
var argument = SyntaxFactory.Argument(name);
var missingArgument = SyntaxFactory.Argument(missingName);

// make a large list that has lots of zero-length nodes (that shouldn't be found)
var nodesAndTokens = SyntaxFactory.NodeOrTokenList(
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
argument);

var argumentList = SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList<ArgumentSyntax>(SyntaxFactory.NodeOrTokenList(nodesAndTokens)));
var invocation = SyntaxFactory.InvocationExpression(name, argumentList);
CheckFindToken(invocation);
}

private void CheckFindToken(SyntaxNode node)
{
for (int i = node.FullSpan.End - 1; i >= 0; i--)
{
var token = node.FindToken(i);
Assert.Equal(true, token.FullSpan.Contains(i));
}
}

[WorkItem(755236, "DevDiv")]
[Fact]
public void TestFindNode()
Expand Down

0 comments on commit 3799cae

Please sign in to comment.