Пример #1
0
        private static void CleanupSourceMappingEnd(FormattingContext context, Range sourceMappingRange, List <TextChange> changes)
        {
            //
            // We look through every source mapping that intersects with the affected range and
            // bring the content after the last line to its own line and adjust its indentation,
            //
            // E.g,
            //
            // @{
            //     if (true)
            //     {  <div></div>
            //     }
            // }
            //
            // becomes,
            //
            // @{
            //    if (true)
            //    {
            //        </div></div>
            //    }
            // }
            //

            var text = context.SourceText;
            var sourceMappingSpan   = sourceMappingRange.AsTextSpan(text);
            var mappingEndLineIndex = sourceMappingRange.End.Line;

            if (!context.Indentations[mappingEndLineIndex].StartsInCSharpContext)
            {
                // For corner cases like (Position marked with |),
                // It is already in a separate line. It doesn't need cleaning up.
                // @{
                //     if (true}
                //     {
                //         |<div></div>
                //     }
                // }
                //
                return;
            }

            var endSpan = TextSpan.FromBounds(sourceMappingSpan.End, sourceMappingSpan.End);

            if (!ShouldFormat(context, endSpan, allowImplicitStatements: false))
            {
                // We don't want to run cleanup on this range.
                return;
            }

            var contentStartOffset = text.Lines[mappingEndLineIndex].GetFirstNonWhitespaceOffset(sourceMappingRange.End.Character);

            if (contentStartOffset == null)
            {
                // There is no content after the end of this source mapping. No need to clean up.
                return;
            }

            var spanToReplace = new TextSpan(sourceMappingSpan.End, 0);

            if (!context.TryGetIndentationLevel(spanToReplace.End, out var contentIndentLevel))
            {
                // Can't find the correct indentation for this content. Leave it alone.
                return;
            }

            // At this point, `contentIndentLevel` should contain the correct indentation level for `}` in the above example.
            var replacement = context.NewLineString + context.GetIndentationLevelString(contentIndentLevel);

            // After the below change the above example should look like,
            // @{
            //     if (true)
            //     {
            //         <div></div>
            //     }
            // }
            var change = new TextChange(spanToReplace, replacement);

            changes.Add(change);
        }
Пример #2
0
        private SourceText CleanupDocument(FormattingContext context, Range range = null)
        {
            //
            // We look through every source mapping that intersects with the affected range and
            // adjust the indentation of the first line,
            //
            // E.g,
            //
            // @{   public int x = 0;
            // }
            //
            // becomes,
            //
            // @{
            //    public int x  = 0;
            // }
            //
            var text = context.SourceText;

            range ??= TextSpan.FromBounds(0, text.Length).AsRange(text);
            var csharpDocument = context.CodeDocument.GetCSharpDocument();

            var changes = new List <TextChange>();

            foreach (var mapping in csharpDocument.SourceMappings)
            {
                var mappingSpan  = new TextSpan(mapping.OriginalSpan.AbsoluteIndex, mapping.OriginalSpan.Length);
                var mappingRange = mappingSpan.AsRange(text);
                if (!range.LineOverlapsWith(mappingRange))
                {
                    // We don't care about this range. It didn't change.
                    continue;
                }

                var mappingStartLineIndex = (int)mappingRange.Start.Line;
                if (context.Indentations[mappingStartLineIndex].StartsInCSharpContext)
                {
                    // Doesn't need cleaning up.
                    // For corner cases like (Range marked with |...|),
                    // @{
                    //     if (true} { <div></div>| }|
                    // }
                    // We want to leave it alone because tackling it here is really complicated.
                    continue;
                }

                // @{
                //     if (true)
                //     {
                //         <div></div>|
                //
                //              |}
                // }
                // We want to return the length of the range marked by |...|
                //
                var whitespaceLength = text.GetFirstNonWhitespaceOffset(mappingSpan);
                if (whitespaceLength == null)
                {
                    // There was no content here. Skip.
                    continue;
                }

                var spanToReplace = new TextSpan(mappingSpan.Start, whitespaceLength.Value);
                if (!context.TryGetIndentationLevel(spanToReplace.End, out var contentIndentLevel))
                {
                    // Can't find the correct indentation for this content. Leave it alone.
                    continue;
                }

                // At this point, `contentIndentLevel` should contain the correct indentation level for `}` in the above example.
                var replacement = context.NewLineString + context.GetIndentationLevelString(contentIndentLevel);

                // After the below change the above example should look like,
                // @{
                //     if (true)
                //     {
                //         <div></div>
                //     }
                // }
                var change = new TextChange(spanToReplace, replacement);
                changes.Add(change);
            }

            var changedText = text.WithChanges(changes);

            return(changedText);
        }
Пример #3
0
        private static void CleanupSourceMappingStart(FormattingContext context, Range sourceMappingRange, List <TextChange> changes)
        {
            //
            // We look through every source mapping that intersects with the affected range and
            // bring the first line to its own line and adjust its indentation,
            //
            // E.g,
            //
            // @{   public int x = 0;
            // }
            //
            // becomes,
            //
            // @{
            //    public int x  = 0;
            // }
            //

            var text = context.SourceText;
            var sourceMappingSpan = sourceMappingRange.AsTextSpan(text);

            if (!ShouldFormat(context, sourceMappingSpan, allowImplicitStatements: false))
            {
                // We don't want to run cleanup on this range.
                return;
            }

            if (sourceMappingRange.Start.Character == 0)
            {
                // It already starts on a fresh new line which doesn't need cleanup.
                // E.g, (The mapping starts at | in the below case)
                // @{
                //     @: Some html
                // |   var x = 123;
                // }
                //

                return;
            }

            // @{
            //     if (true)
            //     {
            //         <div></div>|
            //
            //              |}
            // }
            // We want to return the length of the range marked by |...|
            //
            var whitespaceLength = text.GetFirstNonWhitespaceOffset(sourceMappingSpan, out var newLineCount);

            if (whitespaceLength == null)
            {
                // There was no content after the start of this mapping. Meaning it already is clean.
                // E.g,
                // @{|
                //    ...
                // }

                return;
            }

            var spanToReplace = new TextSpan(sourceMappingSpan.Start, whitespaceLength.Value);

            if (!context.TryGetIndentationLevel(spanToReplace.End, out var contentIndentLevel))
            {
                // Can't find the correct indentation for this content. Leave it alone.
                return;
            }

            // At this point, `contentIndentLevel` should contain the correct indentation level for `}` in the above example.
            // Make sure to preserve the same number of blank lines as the original string had
            var replacement = PrependLines(context.GetIndentationLevelString(contentIndentLevel), context.NewLineString, Math.Max(newLineCount, 1));

            // After the below change the above example should look like,
            // @{
            //     if (true)
            //     {
            //         <div></div>
            //     }
            // }
            var change = new TextChange(spanToReplace, replacement);

            changes.Add(change);
        }
        private void CleanupSourceMappingStart(FormattingContext context, Range sourceMappingRange, List <TextChange> changes)
        {
            //
            // We look through every source mapping that intersects with the affected range and
            // bring the first line to its own line and adjust its indentation,
            //
            // E.g,
            //
            // @{   public int x = 0;
            // }
            //
            // becomes,
            //
            // @{
            //    public int x  = 0;
            // }
            //

            if (!ShouldFormat(context, sourceMappingRange.Start, allowImplicitStatements: false))
            {
                // We don't want to run cleanup on this range.
                return;
            }

            // @{
            //     if (true)
            //     {
            //         <div></div>|
            //
            //              |}
            // }
            // We want to return the length of the range marked by |...|
            //
            var text = context.SourceText;
            var sourceMappingSpan = sourceMappingRange.AsTextSpan(text);
            var whitespaceLength  = text.GetFirstNonWhitespaceOffset(sourceMappingSpan);

            if (whitespaceLength == null)
            {
                // There was no content here. Skip.
                return;
            }

            var spanToReplace = new TextSpan(sourceMappingSpan.Start, whitespaceLength.Value);

            if (!context.TryGetIndentationLevel(spanToReplace.End, out var contentIndentLevel))
            {
                // Can't find the correct indentation for this content. Leave it alone.
                return;
            }

            // At this point, `contentIndentLevel` should contain the correct indentation level for `}` in the above example.
            var replacement = context.NewLineString + context.GetIndentationLevelString(contentIndentLevel);

            // After the below change the above example should look like,
            // @{
            //     if (true)
            //     {
            //         <div></div>
            //     }
            // }
            var change = new TextChange(spanToReplace, replacement);

            changes.Add(change);
        }