/// <summary> /// Returns a function that returns true if a given fragment does not overlap with the specified range. /// </summary> internal static Func <CodeFragment, bool> NotOverlappingWith(Range relRange) => token => token.IsWithinRange(new Range { Start = new Position(0, 0), End = relRange.Start }) || (ContextBuilder.TokensAfter(relRange.End))(token);
/// <summary> /// Returns all code fragments in the specified file that overlap with the given range. /// Returns an empty sequence if any of the given arguments is null. /// </summary> private static IEnumerable <CodeFragment> FragmentsOverlappingWithRange(this FileContentManager file, LSP.Range range) { if (file == null || range?.Start == null || range.End == null) { return(Enumerable.Empty <CodeFragment>()); } var(start, end) = (range.Start.Line, range.End.Line); var fragAtStart = file.TryGetFragmentAt(range.Start, out var _, includeEnd: true); var inRange = file.GetTokenizedLine(start).Select(t => t.WithUpdatedLineNumber(start)).Where(ContextBuilder.TokensAfter(range.Start)); // does not include fragAtStart inRange = start == end ? inRange.Where(ContextBuilder.TokensStartingBefore(range.End)) : inRange.Concat(file.GetTokenizedLines(start + 1, end - start - 1).SelectMany((x, i) => x.Select(t => t.WithUpdatedLineNumber(start + 1 + i)))) .Concat(file.GetTokenizedLine(end).Select(t => t.WithUpdatedLineNumber(end)).Where(ContextBuilder.TokensStartingBefore(range.End))); var fragments = ImmutableArray.CreateBuilder <CodeFragment>(); if (fragAtStart != null) { fragments.Add(fragAtStart); } fragments.AddRange(inRange); return(fragments.ToImmutableArray()); }