提交 b106d3d4 编写于 作者: M Matt Warren

Change Slot lookup to use BinarySearchUpperBound

上级 3799cae7
......@@ -52,20 +52,7 @@ public override int GetSlotOffset(int index)
public override int FindSlotIndexContainingOffset(int offset)
{
Debug.Assert(offset >= 0 && offset < FullWidth);
int idx = _childOffsets.BinarySearch(offset);
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;
return _childOffsets.BinarySearchUpperBound(offset) - 1;
}
private static int[] CalculateOffsets(ArrayElement<CSharpSyntaxNode>[] children)
......
......@@ -512,7 +512,7 @@ public void TestFindTokenInLargeList()
private void CheckFindToken(SyntaxNode node)
{
for (int i = node.FullSpan.End - 1; i >= 0; i--)
for (int i = 0; i < node.FullSpan.End; i++)
{
var token = node.FindToken(i);
Assert.Equal(true, token.FullSpan.Contains(i));
......
......@@ -173,5 +173,35 @@ internal static int BinarySearch(this int[] array, int value)
return ~low;
}
/// <summary>
/// Search a sorted integer array for the target value in O(log N) time.
/// </summary>
/// <param name="array">The array of integers which must be sorted in ascending order.</param>
/// <param name="value">The target value.</param>
/// <returns>An index in the array pointing to the position where <paramref name="value"/> should be
/// inserted in order to maintain the sorted order. All values to the right of this position will be
/// strictly greater than <paramref name="value"/>. Note that this may return a position off the end
/// of the array if all elements are less than or equal to <paramref name="value"/>.</returns>
internal static int BinarySearchUpperBound(this int[] array, int value)
{
int low = 0;
int high = array.Length - 1;
while (low <= high)
{
int middle = low + ((high - low) >> 1);
if (array[middle] > value)
{
high = middle - 1;
}
else
{
low = middle + 1;
}
}
return low;
}
}
}
......@@ -466,8 +466,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
''' </remarks>
Public Overrides Function FindSlotIndexContainingOffset(offset As Integer) As Integer
Debug.Assert(offset >= 0 AndAlso offset < FullWidth)
Dim idx = _childOffsets.BinarySearch(offset)
Return If(idx >= 0, idx, (Not idx) - 1)
Return _childOffsets.BinarySearchUpperBound(offset) - 1
End Function
Friend Overrides Function SetDiagnostics(errors() As DiagnosticInfo) As GreenNode
......
......@@ -2114,6 +2114,41 @@ End Class]]>
Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl.FindNode(root.FullSpan))
End Sub
<Fact>
Public Sub TestFindTokenInLargeList()
Dim identifier = SyntaxFactory.Identifier("x")
Dim missingIdentifier = SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken)
Dim name = SyntaxFactory.IdentifierName(identifier)
Dim missingName = SyntaxFactory.IdentifierName(missingIdentifier)
Dim comma = SyntaxFactory.Token(SyntaxKind.CommaToken)
Dim missingComma = SyntaxFactory.MissingToken(SyntaxKind.CommaToken)
Dim argument = SyntaxFactory.SimpleArgument(name)
Dim missingArgument = SyntaxFactory.SimpleArgument(missingName)
'' make a large list that has lots of zero-length nodes (that shouldn't be found)
Dim nodesAndTokens = SyntaxFactory.NodeOrTokenList(
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
missingArgument, missingComma,
argument)
Dim argumentList = SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(Of ArgumentSyntax)(SyntaxFactory.NodeOrTokenList(nodesAndTokens)))
Dim invocation = SyntaxFactory.InvocationExpression(name, argumentList)
CheckFindToken(invocation)
End Sub
Private Sub CheckFindToken(node As SyntaxNode)
For i As Integer = 1 To node.FullSpan.End - 1
Dim token = node.FindToken(i)
Assert.Equal(True, token.FullSpan.Contains(i))
Next
End Sub
<WorkItem(539940, "DevDiv")>
<Fact>
Public Sub TestFindTriviaNoTriviaExistsAtPosition()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册