async Task <HighlightedLine> ISyntaxHighlighting.GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { if (line == null) { throw new ArgumentNullException(nameof(line)); } if (!DefaultSourceEditorOptions.Instance.EnableSemanticHighlighting) { return(await syntaxMode.GetHighlightedLineAsync(line, cancellationToken)); } var syntaxLine = await syntaxMode.GetHighlightedLineAsync(line, cancellationToken).ConfigureAwait(false); if (syntaxLine.Segments.Count == 0) { return(syntaxLine); } lock (lineSegments) { var segments = new List <ColoredSegment> (syntaxLine.Segments); int endOffset = segments [segments.Count - 1].EndOffset; try { var tree = lineSegments.FirstOrDefault(t => t.Item1 == line); int lineOffset = line.Offset; if (tree == null) { tree = Tuple.Create(line, new HighlightingSegmentTree()); tree.Item2.InstallListener(editor.Document); foreach (var seg2 in semanticHighlighting.GetColoredSegments(new TextSegment(lineOffset, line.Length))) { tree.Item2.AddStyle(seg2, seg2.ColorStyleKey); } while (lineSegments.Count > MaximumCachedLineSegments) { var removed = lineSegments.Dequeue(); try { removed.Item2.RemoveListener(); } catch (Exception) { } } lineSegments.Enqueue(tree); } foreach (var treeseg in tree.Item2.GetSegmentsOverlapping(line)) { var inLineStartOffset = Math.Max(0, treeseg.Offset - lineOffset); var inLineEndOffset = Math.Min(line.Length, treeseg.EndOffset - lineOffset); if (inLineEndOffset <= inLineStartOffset) { continue; } var semanticSegment = new ColoredSegment(inLineStartOffset, inLineEndOffset - inLineStartOffset, syntaxLine.Segments [0].ScopeStack.Push(treeseg.Style)); SyntaxHighlighting.ReplaceSegment(segments, semanticSegment); } } catch (Exception e) { LoggingService.LogError("Error in semantic highlighting: " + e); return(syntaxLine); } return(new HighlightedLine(line, segments)); } }
async Task <HighlightedLine> ISyntaxHighlighting.GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { if (line == null) { throw new ArgumentNullException(nameof(line)); } if (!DefaultSourceEditorOptions.Instance.EnableSemanticHighlighting) { return(await syntaxMode.GetHighlightedLineAsync(line, cancellationToken)); } var syntaxLine = await syntaxMode.GetHighlightedLineAsync(line, cancellationToken).ConfigureAwait(false); if (syntaxLine.Segments.Count == 0) { return(syntaxLine); } var segments = new List <ColoredSegment> (syntaxLine.Segments); int endOffset = segments [segments.Count - 1].EndOffset; try { // This code should not have any lambda capture linq, as it is a hot loop. int lineOffset = line.Offset; foreach (var treeseg in semanticHighlighting.GetColoredSegments(new TextSegment(lineOffset, line.Length))) { var inLineStartOffset = Math.Max(0, treeseg.Offset - lineOffset); var inLineEndOffset = Math.Min(line.Length, treeseg.EndOffset - lineOffset); if (inLineEndOffset <= inLineStartOffset) { continue; } var semanticSegment = new ColoredSegment(inLineStartOffset, inLineEndOffset - inLineStartOffset, treeseg.ScopeStack); SyntaxHighlighting.ReplaceSegment(segments, semanticSegment); } } catch (Exception e) { LoggingService.LogError("Error in semantic highlighting: ", e); return(syntaxLine); } return(new HighlightedLine(line, segments)); }