int IIntervalIntrospector <RelativeIndentationData> .GetLength(RelativeIndentationData value)
 {
     return(value.InseparableRegionSpan.Length);
 }
Beispiel #2
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);
        }
 int IIntervalIntrospector <RelativeIndentationData> .GetStart(RelativeIndentationData value)
 {
     return(value.InseparableRegionSpan.Start);
 }