示例#1
0
        public static HighlightSpan CreateHighlightSpan(ClassifiedSpan span, TextLineCollection lines, IEnumerable <string> projects)
        {
            var linePos = lines.GetLinePositionSpan(span.TextSpan);

            return(new HighlightSpan
            {
                StartLine = linePos.Start.Line,
                EndLine = linePos.End.Line,
                StartColumn = linePos.Start.Character,
                EndColumn = linePos.End.Character,
                Kind = span.ClassificationType,
                Projects = projects
            });
        }
        private static SemanticHighlightSpan CreateSemanticSpan(IEnumerable <ClassifiedResult> results, TextLineCollection lines)
        {
            var additiveResults = results.Where(result => ClassificationTypeNames.AdditiveTypeNames.Contains(result.Span.ClassificationType));
            var modifiers       = additiveResults.Select(result => _modifierMap[result.Span.ClassificationType]).ToArray();

            var result = results.Except(additiveResults).Single();
            var span   = result.Span;

            var linePos = lines.GetLinePositionSpan(span.TextSpan);

            return(new SemanticHighlightSpan
            {
                StartLine = linePos.Start.Line,
                EndLine = linePos.End.Line,
                StartColumn = linePos.Start.Character,
                EndColumn = linePos.End.Character,
                Type = _classificationMap[span.ClassificationType],
                Modifiers = modifiers
            });
        }
示例#3
0
 public static int GetLineCount(this TextLineCollection textLines, TextSpan span)
 {
     return(textLines.GetLinePositionSpan(span).GetLineCount());
 }
示例#4
0
        private static int ComputeNextToken(
            TextLineCollection lines,
            ref int lastLineNumber,
            ref int lastStartCharacter,
            ClassifiedSpan[] classifiedSpans,
            int currentClassifiedSpanIndex,
            Dictionary <string, int> tokenTypesToIndex,
            out int deltaLineOut,
            out int startCharacterDeltaOut,
            out int tokenLengthOut,
            out int tokenTypeOut,
            out int tokenModifiersOut)
        {
            // Each semantic token is represented in LSP by five numbers:
            //     1. Token line number delta, relative to the previous token
            //     2. Token start character delta, relative to the previous token
            //     3. Token length
            //     4. Token type (index) - looked up in SemanticTokensLegend.tokenTypes
            //     5. Token modifiers - each set bit will be looked up in SemanticTokensLegend.tokenModifiers

            var classifiedSpan   = classifiedSpans[currentClassifiedSpanIndex];
            var originalTextSpan = classifiedSpan.TextSpan;
            var linePosition     = lines.GetLinePositionSpan(originalTextSpan).Start;
            var lineNumber       = linePosition.Line;

            // 1. Token line number delta, relative to the previous token
            var deltaLine = lineNumber - lastLineNumber;

            Contract.ThrowIfTrue(deltaLine < 0, $"deltaLine is less than 0: {deltaLine}");

            // 2. Token start character delta, relative to the previous token
            // (Relative to 0 or the previous token’s start if they're on the same line)
            var deltaStartCharacter = linePosition.Character;

            if (lastLineNumber == lineNumber)
            {
                deltaStartCharacter -= lastStartCharacter;
            }

            lastLineNumber     = lineNumber;
            lastStartCharacter = linePosition.Character;

            // 3. Token length
            var tokenLength = originalTextSpan.Length;

            // We currently only have one modifier (static). The logic below will need to change in the future if other
            // modifiers are added in the future.
            var modifierBits   = TokenModifiers.None;
            var tokenTypeIndex = 0;

            // Classified spans with the same text span should be combined into one token.
            while (classifiedSpans[currentClassifiedSpanIndex].TextSpan == originalTextSpan)
            {
                var classificationType = classifiedSpans[currentClassifiedSpanIndex].ClassificationType;
                if (classificationType != ClassificationTypeNames.StaticSymbol)
                {
                    // 4. Token type - looked up in SemanticTokensLegend.tokenTypes (language server defined mapping
                    // from integer to LSP token types).
                    tokenTypeIndex = GetTokenTypeIndex(classificationType, tokenTypesToIndex);
                }
                else
                {
                    // 5. Token modifiers - each set bit will be looked up in SemanticTokensLegend.tokenModifiers
                    modifierBits = TokenModifiers.Static;
                }

                // Break out of the loop if we have no more classified spans left, or if the next classified span has
                // a different text span than our current text span.
                if (currentClassifiedSpanIndex + 1 >= classifiedSpans.Length || classifiedSpans[currentClassifiedSpanIndex + 1].TextSpan != originalTextSpan)
                {
                    break;
                }

                currentClassifiedSpanIndex++;
            }

            deltaLineOut           = deltaLine;
            startCharacterDeltaOut = deltaStartCharacter;
            tokenLengthOut         = tokenLength;
            tokenTypeOut           = tokenTypeIndex;
            tokenModifiersOut      = (int)modifierBits;

            return(currentClassifiedSpanIndex);
        }