/// <summary> /// Returns true if the given file contains any tokens overlapping with the given fragment. /// The range of the tokens in the file is assumed to be relative to their start line (the index at which they are listed), /// whereas the range of the given fragment is assumed to be the absolute range. /// </summary> /// <exception cref="ArgumentOutOfRangeException"><paramref name="range"/> is not a valid range within <paramref name="file"/>.</exception> internal static bool ContainsTokensOverlappingWith(this FileContentManager file, Range range) { if (!file.ContainsRange(range)) { throw new ArgumentOutOfRangeException(nameof(range)); } var(start, end) = (range.Start.Line, range.End.Line); if (start != end && file.GetTokenizedLines(start + 1, end - start - 1).SelectMany(x => x).Any()) { return(true); } var inRange = file.GetTokenizedLine(start).Where(TokensAfter(Position.Create(0, range.Start.Column))); // checking tokens overlapping with range.Start below inRange = start == end ? inRange.Where(TokensStartingBefore(Position.Create(0, range.End.Column))) : inRange.Concat(file.GetTokenizedLine(end).Where(TokensStartingBefore(Position.Create(0, range.End.Column)))); if (inRange.Any()) { QsCompilerError.Raise($"{range.DiagnosticString()} overlaps for start = {start}, end = {end}, \n\n" + $"{string.Join("\n", file.GetTokenizedLine(start).Select(x => $"{x.Range.DiagnosticString()}"))},\n\n " + $"{string.Join("\n", file.GetTokenizedLine(end).Select(x => $"{x.Range.DiagnosticString()}"))},"); return(true); } var overlapsWithStart = file.TryGetFragmentAt(range.Start, out _); return(overlapsWithStart != null); }
/// <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()); }