示例#1
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;
        }
示例#2
0
        /// <summary>
        /// Affected range of a change is the range within which nodes can be affected by a change
        /// and cannot be reused. Because of lookahead effective range of a change is larger than
        /// the change itself.
        /// </summary>
        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 somwhere 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);
        }