Esempio n. 1
0
        public bool TryGetEndTokenForRelativeIndentationSpan(SyntaxToken token, int maxChainDepth, out SyntaxToken endToken, CancellationToken cancellationToken)
        {
            endToken = default;

            var depth = 0;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (depth++ > maxChainDepth)
                {
                    return(false);
                }

                var span            = token.Span;
                var indentationData = _relativeIndentationTree.GetSmallestContainingInterval(span.Start, 0);
                if (indentationData == null)
                {
                    // this means the given token is not inside of inseparable regions
                    endToken = token;
                    return(true);
                }

                // recursively find the end token outside of inseparable regions
                token = indentationData.EndToken.GetNextToken(includeZeroWidth: true);
                if (token.RawKind == 0)
                {
                    // reached end of tree
                    return(true);
                }
            }
        }
Esempio n. 2
0
        private AnchorData?GetAnchorData(SyntaxToken token)
        {
            var span = token.Span;

            var anchorData = _anchorTree.GetSmallestContainingInterval(span.Start, 0);

            if (anchorData == null)
            {
                // no anchor
                DebugCheckEmpty(_anchorTree, new TextSpan(span.Start, 0));
                return(null);
            }

            return(anchorData);
        }
Esempio n. 3
0
        public SyntaxToken GetEndTokenForRelativeIndentationSpan(SyntaxToken token)
        {
            var span            = token.Span;
            var indentationData = _relativeIndentationTree.GetSmallestContainingInterval(span.Start, 0);

            if (indentationData == null)
            {
                // this means the given token is not inside of inseparable regions
                return(token);
            }

            // recursively find the end token outside of inseparable regions
            var nextToken = indentationData.EndToken.GetNextToken(includeZeroWidth: true);

            if (nextToken.RawKind == 0)
            {
                // reached end of tree
                return(default(SyntaxToken));
            }

            return(GetEndTokenForRelativeIndentationSpan(nextToken));
        }
Esempio n. 4
0
        public void AddIndentBlockOperation(IndentBlockOperation operation)
        {
            var intervalTreeSpan = operation.TextSpan;

            // don't add stuff if it is empty
            if (intervalTreeSpan.IsEmpty ||
                _indentationMap.Contains(intervalTreeSpan))
            {
                return;
            }

            // relative indentation case where indentation depends on other token
            if (operation.IsRelativeIndentation)
            {
                var effectiveBaseToken = operation.Option.IsOn(IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine) ? _tokenStream.FirstTokenOfBaseTokenLine(operation.BaseToken) : operation.BaseToken;
                var inseparableRegionStartingPosition = effectiveBaseToken.FullSpan.Start;
                var relativeIndentationGetter         = new Lazy <int>(() =>
                {
                    var baseIndentationDelta = operation.GetAdjustedIndentationDelta(_engine.SyntaxFacts, TreeData.Root, effectiveBaseToken);
                    var indentationDelta     = baseIndentationDelta * this.Options.GetOption(FormattingOptions2.IndentationSize);

                    // baseIndentation is calculated for the adjusted token if option is RelativeToFirstTokenOnBaseTokenLine
                    var baseIndentation = _tokenStream.GetCurrentColumn(operation.Option.IsOn(IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine) ?
                                                                        _tokenStream.FirstTokenOfBaseTokenLine(operation.BaseToken) :
                                                                        operation.BaseToken);

                    return(baseIndentation + indentationDelta);
                }, isThreadSafe: true);

                // set new indentation
                var relativeIndentationData = new RelativeIndentationData(inseparableRegionStartingPosition, intervalTreeSpan, operation, relativeIndentationGetter);

                _indentationTree.AddIntervalInPlace(relativeIndentationData);
                _relativeIndentationTree.AddIntervalInPlace(relativeIndentationData);
                _indentationMap.Add(intervalTreeSpan);

                return;
            }

            // absolute position case
            if (operation.Option.IsOn(IndentBlockOption.AbsolutePosition))
            {
                _indentationTree.AddIntervalInPlace(new SimpleIndentationData(intervalTreeSpan, operation.IndentationDeltaOrPosition));
                _indentationMap.Add(intervalTreeSpan);
                return;
            }

            // regular indentation case where indentation is based on its previous indentation
            var indentationData = _indentationTree.GetSmallestContainingInterval(operation.TextSpan.Start, 0);

            if (indentationData == null)
            {
                // no previous indentation
                var indentation = operation.IndentationDeltaOrPosition * this.Options.GetOption(FormattingOptions2.IndentationSize);
                _indentationTree.AddIntervalInPlace(new SimpleIndentationData(intervalTreeSpan, indentation));
                _indentationMap.Add(intervalTreeSpan);
                return;
            }

            // get indentation based on its previous indentation
            var indentationGetter = new Lazy <int>(() =>
            {
                var indentationDelta = operation.IndentationDeltaOrPosition * this.Options.GetOption(FormattingOptions2.IndentationSize);

                return(indentationData.Indentation + indentationDelta);
            }, isThreadSafe: true);

            // set new indentation
            _indentationTree.AddIntervalInPlace(new LazyIndentationData(intervalTreeSpan, indentationGetter));
            _indentationMap.Add(intervalTreeSpan);
        }