Beispiel #1
0
        private static TextChangeRange ExtendToAffectedRange(
            CSharp.CSharpSyntaxNode oldTree,
            TextChangeRange changeRange
            )
        {
            // we will increase affected range of the change by the number of lookahead tokens
            // original code in Blender seem to imply the lookahead at the end of a node is 1 token
            // max. TODO: 1 token lookahead seems a bit too optimistic. Increase if needed.
            const int maxLookahead = 1;

            // check if change is not after the end. TODO: there should be an assert somewhere about
            // changes starting at least at the End of old tree
            var lastCharIndex = oldTree.FullWidth - 1;

            // Move the start of the change range so that it is contained within oldTree.
            var start = Math.Max(Math.Min(changeRange.Span.Start, lastCharIndex), 0);

            // the first iteration aligns us with the change start. subsequent iteration move us to
            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
            // start of the tree.  Also, the tokens we get back may be zero width.  In that case we
            // need to keep on looking backward.
            for (var i = 0; start > 0 && i <= maxLookahead;)
            {
                var token = oldTree.FindToken(start, findInsideTrivia: false);
                Debug.Assert(
                    token.Kind() != SyntaxKind.None,
                    "how could we not get a real token back?"
                    );

                start = Math.Max(0, token.Position - 1);

                // Only increment i if we got a non-zero width token.  Otherwise, we want to just do
                // this again having moved back one space.
                if (token.FullWidth > 0)
                {
                    i++;
                }
            }

            if (IsInsideInterpolation(oldTree, start))
            {
                // If the changed range starts inside an interpolated string, we
                // move the start of the change range to the beginning of the line so that any
                // interpolated string literal in the changed range will be scanned in its entirety.
                var column =
                    oldTree.SyntaxTree.GetLineSpan(new TextSpan(start, 0)).Span.Start.Character;
                start = Math.Max(start - column, 0);
            }

            var finalSpan   = TextSpan.FromBounds(start, changeRange.Span.End);
            var finalLength = changeRange.NewLength + (changeRange.Span.Start - start);

            return(new TextChangeRange(finalSpan, finalLength));
        }
Beispiel #2
0
        private static bool IsInsideInterpolation(CSharp.CSharpSyntaxNode oldTree, int start)
        {
            var token = oldTree.FindToken(start, findInsideTrivia: false);

            for (var parent = token.Parent; // for each parent
                 parent != null;
                 parent = parent.Parent)
            {
                if (parent.Kind() == SyntaxKind.InterpolatedStringExpression)
                {
                    return(true);
                }
            }

            return(false);
        }