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));
            }
        }
Esempio n. 2
0
        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));
        }