public static Range Overlap(this Range range, Range other)
        {
            if (range is null)
            {
                throw new ArgumentNullException(nameof(range));
            }

            if (other is null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            var overlapStart = range.Start;

            if (range.Start.CompareTo(other.Start) < 0)
            {
                overlapStart = other.Start;
            }

            var overlapEnd = range.End;

            if (range.End.CompareTo(other.End) > 0)
            {
                overlapEnd = other.End;
            }

            // Empty ranges do not overlap with any range.
            if (overlapStart.CompareTo(overlapEnd) < 0)
            {
                return(new Range(overlapStart, overlapEnd));
            }

            return(null);
        }
        private static TextSpan FromRange(BicepFile bicepFile, Range range)
        {
            var position = TextCoordinateConverter.GetOffset(bicepFile.LineStarts, range.Start.Line, range.Start.Character);
            var length   = TextCoordinateConverter.GetOffset(bicepFile.LineStarts, range.End.Line, range.End.Character) - position;

            return(new TextSpan(position, length));
        }
Example #3
0
 public BicepCompletionContext(
     BicepCompletionContextKind kind,
     Range replacementRange,
     SyntaxBase?enclosingDeclaration,
     ObjectSyntax? @object,
     ObjectPropertySyntax?property,
     ArraySyntax?array,
     PropertyAccessSyntax?propertyAccess,
     ResourceAccessSyntax?resourceAccess,
     ArrayAccessSyntax?arrayAccess,
     TargetScopeSyntax?targetScope,
     ImmutableArray <ILanguageScope> activeScopes)
 {
     this.Kind                 = kind;
     this.ReplacementRange     = replacementRange;
     this.EnclosingDeclaration = enclosingDeclaration;
     this.Object               = @object;
     this.Property             = property;
     this.Array                = array;
     this.PropertyAccess       = propertyAccess;
     this.ResourceAccess       = resourceAccess;
     this.ArrayAccess          = arrayAccess;
     this.TargetScope          = targetScope;
     this.ActiveScopes         = activeScopes;
 }
Example #4
0
 /// <summary>
 /// Push a token onto the builder
 /// </summary>
 /// <remarks>Avoid creating the range just to call this method</remarks>
 /// <param name="range">The range, cannot span multiple lines</param>
 /// <param name="tokenType"></param>
 /// <param name="tokenModifiers"></param>
 public void Push(Range range, int tokenType, int tokenModifiers)
 {
     if (range.Start.Line != range.End.Line)
     {
         throw new ArgumentOutOfRangeException(nameof(range), "Range must not span multiple lines");
     }
     Push(range.Start.Line, range.Start.Character, range.End.Character - range.Start.Character, tokenType, tokenModifiers);
 }
        public static TextSpan AsTextSpan(this Range range, SourceText sourceText)
        {
            if (range is null)
            {
                throw new ArgumentNullException(nameof(range));
            }

            if (sourceText is null)
            {
                throw new ArgumentNullException(nameof(sourceText));
            }

            var start = sourceText.Lines[(int)range.Start.Line].Start + (int)range.Start.Character;
            var end   = sourceText.Lines[(int)range.End.Line].Start + (int)range.End.Character;

            return(new TextSpan(start, end - start));
        }
 public BicepCompletionContext(
     BicepCompletionContextKind kind,
     Range replacementRange,
     SyntaxBase?enclosingDeclaration,
     ObjectSyntax? @object,
     ObjectPropertySyntax?property,
     ArraySyntax?array,
     PropertyAccessSyntax?propertyAccess,
     TargetScopeSyntax?targetScope)
 {
     this.Kind                 = kind;
     this.ReplacementRange     = replacementRange;
     this.EnclosingDeclaration = enclosingDeclaration;
     this.Object               = @object;
     this.Property             = property;
     this.Array                = array;
     this.PropertyAccess       = propertyAccess;
     this.TargetScope          = targetScope;
 }
Example #7
0
 public void ShiftLineNumber(int amount)
 {
     LineNumber += amount;
     Range?.ShiftLineNumber(amount);
     CommentRange?.ShiftLineNumber(amount);
     ContentRange?.ShiftLineNumber(amount);
     IndentationRange?.ShiftLineNumber(amount);
     MatchedSyntax?.Result?.Matches?.ForEach(m =>
     {
         var expression = (m as ExpressionParseMatch)?.Expression;
         if (expression != null)
         {
             expression.GetAllExpressions().ForEach(expr => expr.Range.ShiftLineNumber(amount));
         }
         else
         {
             m.Range.ShiftLineNumber(amount);
         }
     });
 }
        private static void ExtractBasicNodeInformationFrom(string content, int line,
                                                            out NodeIndentation[] indentations, out Range indentRange, out Range contentRange,
                                                            out Range nodeRange, out Range commentRange, out string commentContent, out string nodeContent)
        {
            var length           = content.Length;
            var indentCharsCount = content.TakeWhile(char.IsWhiteSpace).Count();

            indentations = content.GetNodeIndentations();
            nodeContent  = content;

            nodeRange = RangeExtensions.From(line, 0, content.Length);

            indentRange = RangeExtensions.From(line, 0, indentCharsCount);

            commentRange = RangeExtensions.From(line, length, length);

            commentContent = string.Empty;

            var matchResult = LineRegex.Match(content);

            if (matchResult.Success)
            {
                var contentGroup = matchResult.Groups[1];
                var commentGroup = matchResult.Groups[2];

                var endingSpaces = Math.Clamp(contentGroup.Length - contentGroup.Value.TrimEnd().Length, 0,
                                              int.MaxValue);

                nodeContent    = contentGroup.Value;
                commentContent = commentGroup.Value;
                length         = contentGroup.Value.TrimEnd().Length;
                commentRange.Start.Character = commentGroup.Index - endingSpaces;
                commentRange.End.Character   = (commentGroup.Index - endingSpaces) + (commentGroup.Length + endingSpaces);
            }

            nodeContent  = nodeContent.Trim();
            contentRange = RangeExtensions.From(line, indentCharsCount, length);
        }
Example #9
0
        public SemanticTokens GetSemanticTokens(Range range)
        {
            _prevData = null;

            var data = ImmutableArray <int> .Empty.ToBuilder();

            var currentLine       = 0;
            var currentCharOffset = 0;
            var capturing         = false;
            var innerOffset       = 0;

            for (var i = 0; i < _data.Length; i += 5)
            {
                var lineOffset = _data[i];
                currentLine += lineOffset;
                if (lineOffset > 0)
                {
                    currentCharOffset = 0;
                }
                if (!capturing)
                {
                    if (range.Start.Line == currentLine)
                    {
                        var charOffset = _data[i + 1];
                        var length     = _data[i + 2];
                        // TODO: Do we want to capture partial tokens?
                        // using Sys|tem.Collections.Generic|
                        //           ^^^ do we want a token for 'tem`?
                        if (currentCharOffset + charOffset >= range.Start.Character)
                        {
                            capturing = true;
                            // var overlap = ((currentCharOffset + charOffset) - range.Start.Character);
                            data.AddRange(0, charOffset, length, _data[i + 3], _data[i + 4]);
                            continue;
                        }

                        if (currentCharOffset + charOffset + length >= range.Start.Character)
                        {
                            capturing = true;
                            var overlap = ((currentCharOffset + charOffset + length) - range.Start.Character);
                            data.AddRange(0, 0, overlap, _data[i + 3], _data[i + 4]);
                            innerOffset = charOffset - overlap;
                            continue;
                        }

                        currentCharOffset += charOffset;
                    }
                }
                else
                {
                    if (range.End.Line == currentLine)
                    {
                        var charOffset = _data[i + 1];
                        var length     = _data[i + 2];
                        if (currentCharOffset + charOffset >= range.End.Character)
                        {
                            capturing = false;
                            break;
                        }

                        if (currentCharOffset + charOffset + length >= range.End.Character)
                        {
                            capturing = false;
                            var overlap = ((currentCharOffset + charOffset + length) - range.End.Character);
                            data.AddRange(lineOffset, charOffset, length - overlap, _data[i + 3], _data[i + 4]);
                            break;
                        }

                        currentCharOffset += charOffset;

                        data.AddRange(_data[i], _data[i + 1], _data[i + 2], _data[i + 3], _data[i + 4]);
                    }
                    else
                    {
                        if (innerOffset > 0)
                        {
                            data.AddRange(_data[i], _data[i + 1] - innerOffset, _data[i + 2], _data[i + 3],
                                          _data[i + 4]);
                            innerOffset = 0;
                        }
                        else
                        {
                            data.AddRange(_data[i], _data[i + 1], _data[i + 2], _data[i + 3], _data[i + 4]);
                        }
                    }
                }
            }

            return(new SemanticTokens()
            {
                ResultId = Id,
                Data = data.ToImmutable()
            });
        }
Example #10
0
 /// <summary>
 /// Push a token onto the builder
 /// </summary>
 /// <remarks>Avoid creating the range just to call this method</remarks>
 /// <param name="range">The range, cannot span multiple lines</param>
 /// <param name="tokenType"></param>
 /// <param name="tokenModifiers"></param>
 public void Push(Range range, SemanticTokenType?tokenType, IEnumerable <SemanticTokenModifier> tokenModifiers)
 {
     Push(range, _legend.GetTokenTypeIdentity(tokenType), _legend.GetTokenModifiersIdentity(tokenModifiers));
 }
Example #11
0
 /// <summary>
 /// Push a token onto the builder
 /// </summary>
 /// <remarks>Avoid creating the range just to call this method</remarks>
 /// <param name="range">The range, cannot span multiple lines</param>
 /// <param name="tokenType"></param>
 /// <param name="tokenModifiers"></param>
 public void Push(Range range, SemanticTokenType?tokenType, params SemanticTokenModifier[] tokenModifiers)
 {
     Push(range, _legend.GetTokenTypeIdentity(tokenType), _legend.GetTokenModifiersIdentity(tokenModifiers));
 }
Example #12
0
 /// <summary>
 /// Push a token onto the builder
 /// </summary>
 /// <remarks>Avoid creating the range just to call this method</remarks>
 /// <param name="range">The range, cannot span multiple lines</param>
 /// <param name="tokenType"></param>
 /// <param name="tokenModifiers"></param>
 public void Push(Range range, string tokenType, IEnumerable <string> tokenModifiers)
 {
     Push(range, _legend.GetTokenTypeIdentity(tokenType), _legend.GetTokenModifiersIdentity(tokenModifiers));
 }
 public abstract bool TryMapToProjectedDocumentRange(RazorCodeDocument codeDocument, Range originalRange, [NotNullWhen(true)] out Range?projectedRange);
 public abstract bool TryMapFromProjectedDocumentRange(RazorCodeDocument codeDocument, Range projectedRange, MappingBehavior mappingBehavior, [NotNullWhen(true)] out Range?originalRange);
Example #15
0
 public abstract bool TryMapToProjectedDocumentRange(RazorCodeDocument codeDocument, Range originalRange, out Range projectedRange);
Example #16
0
 /// <summary>
 /// Push a token onto the builder
 /// </summary>
 /// <remarks>Avoid creating the range just to call this method</remarks>
 /// <param name="range">The range, cannot span multiple lines</param>
 /// <param name="tokenType"></param>
 /// <param name="tokenModifiers"></param>
 public void Push(Range range, string tokenType, params string[] tokenModifiers)
 {
     Push(range, _legend.GetTokenTypeIdentity(tokenType), _legend.GetTokenModifiersIdentity(tokenModifiers));
 }
 public abstract bool TryMapFromProjectedDocumentRange(RazorCodeDocument codeDocument, Range projectedRange, MappingBehavior mappingBehavior, out Range originalRange);