Skip to content

Commit

Permalink
Use TextChangeHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeRobich committed Apr 16, 2022
1 parent e5f8c7c commit b346915
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
using Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.Completion;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Text;
using OmniSharp.Extensions;
using OmniSharp.Models;
using OmniSharp.Models.v1.Completion;
using OmniSharp.Roslyn.CSharp.Helpers;
using OmniSharp.Roslyn.Utilities;
using OmniSharp.Utilities;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand All @@ -17,7 +19,6 @@
using CSharpCompletionItem = Microsoft.CodeAnalysis.Completion.CompletionItem;
using CSharpCompletionList = Microsoft.CodeAnalysis.Completion.CompletionList;
using CSharpCompletionService = Microsoft.CodeAnalysis.Completion.CompletionService;
using OmniSharp.Extensions;

namespace OmniSharp.Roslyn.CSharp.Services.Completion
{
Expand Down Expand Up @@ -270,7 +271,7 @@ private static void GetCompletionInfo(
static void handleNonInsertsectingEdit(SourceText sourceText, ref List<LinePositionSpanTextChange>? additionalTextEdits, ref int? adjustedNewPosition, TextChange textChange)
{
additionalTextEdits ??= new();
additionalTextEdits.Add(GetChangeForTextAndSpan(textChange.NewText!, textChange.Span, sourceText));
additionalTextEdits.Add(TextChanges.Convert(sourceText, textChange));

if (adjustedNewPosition is int newPosition)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
Expand All @@ -19,11 +18,12 @@
using OmniSharp.Models.v1.Completion;
using OmniSharp.Options;
using OmniSharp.Roslyn.CSharp.Helpers;
using OmniSharp.Roslyn.Utilities;
using OmniSharp.Utilities;
using Roslyn.Utilities;
using CompletionItem = OmniSharp.Models.v1.Completion.CompletionItem;
using CompletionTriggerKind = OmniSharp.Models.v1.Completion.CompletionTriggerKind;
using CSharpCompletionService = Microsoft.CodeAnalysis.Completion.CompletionService;
using Roslyn.Utilities;

namespace OmniSharp.Roslyn.CSharp.Services.Completion
{
Expand Down Expand Up @@ -207,7 +207,7 @@ public async Task<CompletionResolveResponse> Handle(CompletionResolveRequest req
continue;
}

additionalChanges.Add(CompletionListBuilder.GetChangeForTextAndSpan(textChange.NewText, textChange.Span, sourceText));
additionalChanges.Add(TextChanges.Convert(sourceText, textChange));
}

request.Item.AdditionalTextEdits = additionalChanges;
Expand Down Expand Up @@ -273,7 +273,7 @@ public async Task<CompletionAfterInsertResponse> Handle(CompletionAfterInsertReq

return new CompletionAfterInsertResponse
{
Changes = finalChange.TextChanges.SelectAsArray(changedText, static (c, changedText) => CompletionListBuilder.GetChangeForTextAndSpan(c.NewText, c.Span, changedText)),
Changes = finalChange.TextChanges.SelectAsArray(changedText, static (c, changedText) => TextChanges.Convert(changedText, c)),
Line = finalPosition.Line,
Column = finalPosition.Column,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -17,6 +16,7 @@
using OmniSharp.Models.v1.InlayHints;
using OmniSharp.Options;
using OmniSharp.Roslyn.CSharp.Helpers;
using OmniSharp.Roslyn.Utilities;

#nullable enable

Expand Down Expand Up @@ -157,23 +157,9 @@ public List<InlayHint> MapAndCacheHints(ImmutableArray<OmniSharpInlineHint> rosl

internal static LinePositionSpanTextChange[]? ConvertToTextChanges(TextChange? textChange, SourceText sourceText)
{
if (textChange.HasValue == false)
{
return Array.Empty<LinePositionSpanTextChange>();
}

var changeLinePositionSpan = sourceText.Lines.GetLinePositionSpan(textChange.Value.Span);
return new[]
{
new LinePositionSpanTextChange()
{
NewText = textChange.Value.NewText ?? "",
StartLine = changeLinePositionSpan.Start.Line,
StartColumn = changeLinePositionSpan.Start.Character,
EndLine = changeLinePositionSpan.End.Line,
EndColumn = changeLinePositionSpan.End.Character
}
};
return textChange.HasValue
? new[] { TextChanges.Convert(sourceText, textChange.Value) }
: null;
}

public bool TryGetFromCache(InlayHint hint, out OmniSharpInlineHint roslynHint, [NotNullWhen(true)] out Document? document)
Expand Down
85 changes: 41 additions & 44 deletions src/OmniSharp.Roslyn/Utilities/TextChangeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,54 @@ public static async Task<IEnumerable<LinePositionSpanTextChange>> GetAsync(Docum
return Convert(oldText, changes);
}

public static IEnumerable<LinePositionSpanTextChange> Convert(SourceText oldText, params TextChange[] changes)
public static LinePositionSpanTextChange Convert(SourceText oldText, TextChange change)
{
return Convert(oldText, (IEnumerable<TextChange>)changes);
}
var span = change.Span;
var newText = change.NewText;
var prefix = string.Empty;
var postfix = string.Empty;

public static IEnumerable<LinePositionSpanTextChange> Convert(SourceText oldText, IEnumerable<TextChange> changes)
{
return changes
.OrderByDescending(change => change.Span)
.Select(change =>
{
var span = change.Span;
var newText = change.NewText;
var prefix = string.Empty;
var postfix = string.Empty;
if (newText.Length > 0)
{
// Roslyn computes text changes on character arrays. So it might happen that a
// change starts inbetween \r\n which is OK when you are offset-based but a problem
// when you are line,column-based. This code extends text edits which just overlap
// a with a line break to its full line break

if (newText.Length > 0)
{
// Roslyn computes text changes on character arrays. So it might happen that a
// change starts inbetween \r\n which is OK when you are offset-based but a problem
// when you are line,column-based. This code extends text edits which just overlap
// a with a line break to its full line break
if (span.Start > 0 && newText[0] == '\n' && oldText[span.Start - 1] == '\r')
{
// text: foo\r\nbar\r\nfoo
// edit: [----)
span = TextSpan.FromBounds(span.Start - 1, span.End);
prefix = "\r";
}

if (span.Start > 0 && newText[0] == '\n' && oldText[span.Start - 1] == '\r')
{
// text: foo\r\nbar\r\nfoo
// edit: [----)
span = TextSpan.FromBounds(span.Start - 1, span.End);
prefix = "\r";
}
if (span.End < oldText.Length - 1 && newText[newText.Length - 1] == '\r' && oldText[span.End] == '\n')
{
// text: foo\r\nbar\r\nfoo
// edit: [----)
span = TextSpan.FromBounds(span.Start, span.End + 1);
postfix = "\n";
}
}

if (span.End < oldText.Length - 1 && newText[newText.Length - 1] == '\r' && oldText[span.End] == '\n')
{
// text: foo\r\nbar\r\nfoo
// edit: [----)
span = TextSpan.FromBounds(span.Start, span.End + 1);
postfix = "\n";
}
}
var linePositionSpan = oldText.Lines.GetLinePositionSpan(span);

var linePositionSpan = oldText.Lines.GetLinePositionSpan(span);
return new LinePositionSpanTextChange()
{
NewText = prefix + newText + postfix,
StartLine = linePositionSpan.Start.Line,
StartColumn = linePositionSpan.Start.Character,
EndLine = linePositionSpan.End.Line,
EndColumn = linePositionSpan.End.Character
};
}

return new LinePositionSpanTextChange()
{
NewText = prefix + newText + postfix,
StartLine = linePositionSpan.Start.Line,
StartColumn = linePositionSpan.Start.Character,
EndLine = linePositionSpan.End.Line,
EndColumn = linePositionSpan.End.Character
};
});
public static IEnumerable<LinePositionSpanTextChange> Convert(SourceText oldText, IEnumerable<TextChange> changes)
{
return changes
.OrderByDescending(change => change.Span)
.Select(change => Convert(oldText, change));
}
}
}
6 changes: 2 additions & 4 deletions tests/OmniSharp.Tests/LinePositionSpanTextChangeFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ public async Task ExtendsTextChangeAtStart()

var textChange = new TextChange(TextSpan.FromBounds(8, 11), "\n}");

var adjustedTextChanges = TextChanges.Convert(text, textChange);
var adjustedTextChange = TextChanges.Convert(text, textChange);

var adjustedTextChange = adjustedTextChanges.First();
Assert.Equal("\r\n}", adjustedTextChange.NewText);
Assert.Equal(0, adjustedTextChange.StartLine);
Assert.Equal(7, adjustedTextChange.StartColumn);
Expand All @@ -48,9 +47,8 @@ public async Task ExtendsTextChangeAtEnd()

var textChange = new TextChange(TextSpan.FromBounds(5, 7), "\r\n {\r");

var adjustedTextChanges = TextChanges.Convert(text, textChange);
var adjustedTextChange = TextChanges.Convert(text, textChange);

var adjustedTextChange = adjustedTextChanges.First();
Assert.Equal("\r\n {\r\n", adjustedTextChange.NewText);
Assert.Equal(0, adjustedTextChange.StartLine);
Assert.Equal(5, adjustedTextChange.StartColumn);
Expand Down

0 comments on commit b346915

Please sign in to comment.