private SnapshotSpan GetSpanOfPreviousSiblingWorker(SnapshotSpan activeSpan, CancellationToken cancellationToken) { // Find node that covers the entire span. var node = FindLeafNode(activeSpan, cancellationToken); if (node != null) { // Get ancestor with a wider span. var parent = GetEnclosingNode(node.Value); if (parent != null) { // Find node immediately before the current in the children collection. SyntaxNodeOrToken?nodeOrToken = parent.Value .ChildNodesAndTokens() .Reverse() .SkipWhile(child => child != node) .Skip(1) .FirstOrNullable(); if (nodeOrToken.HasValue) { node = nodeOrToken.Value; } else { // If this is the first node, move to the parent so that the user can continue // navigation at the higher level. node = parent.Value; } } } return(node == null ? activeSpan : node.Value.Span.ToSnapshotSpan(activeSpan.Snapshot)); }
private static void ValidateEntries(IEnumerable <SyntaxNodeOrToken> nodeOrTokens) { SyntaxNodeOrToken?last = null; foreach (var nodeOrToken in nodeOrTokens) { // We expect a node if either of the following is true // // * It's the first element // * The last element was a separator // * The current element is a node var requiresValidNode = (last == null || !last.Value.IsNode || nodeOrToken.IsNode); if (requiresValidNode) { var isValidNode = nodeOrToken.IsNode && nodeOrToken.AsNode() is TNode; if (!isValidNode) { throw new ArgumentException(Resources.SeparatedSyntaxListInvalidSequence, nameof(nodeOrTokens)); } } last = nodeOrToken; } }
/// <summary> /// Finds deepest node that covers given <see cref="SnapshotSpan"/>. /// </summary> private SyntaxNodeOrToken?FindLeafNode(SnapshotSpan span, CancellationToken cancellationToken) { if (!TryFindLeafToken(span.Start, out var token, cancellationToken)) { return(null); } SyntaxNodeOrToken?node = token; while (node != null && (span.End.Position > node.Value.Span.End)) { node = GetEnclosingNode(node.Value); } return(node); }
protected override bool TryComputeWeightedDistance(SyntaxNode leftNode, SyntaxNode rightNode, out double distance) { SyntaxNodeOrToken?leftName = TryGetName(leftNode); SyntaxNodeOrToken?rightName = TryGetName(rightNode); Debug.Assert(rightName.HasValue == leftName.HasValue); if (leftName.HasValue) { distance = ComputeDistance(leftName.Value, rightName.Value); return(true); } else { distance = 0; return(false); } }
public bool Equals(SyntaxNodeOrToken?other) { if (other is null) { return(false); } if (IsNode() && other.IsNode()) { return(AsNode() !.Equals(other.AsNode())); } if (IsToken() && other.IsToken()) { return(AsToken() !.Equals(other.AsToken())); } return(false); }
private static TrailingAnalysis?AnalyzeTrailing(SyntaxNodeOrToken?nodeOrToken) { return((nodeOrToken != null) ? AnalyzeTrailing(nodeOrToken.Value) : default);