Родитель
be10de009d
Коммит
e448f97b55
|
@ -23,5 +23,13 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
/// descriptor.
|
||||
/// </summary>
|
||||
UseFirstDescriptor = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// Ignore position indicators (<c>$$</c>) in markup processing. Spans and named spans are still supported in markup.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This flag makes it easier to write tests for code containing interpolated raw strings (<see href="https://github.com/dotnet/roslyn-sdk/issues/1067">dotnet/roslyn-sdk#1067</see>).
|
||||
/// </remarks>
|
||||
TreatPositionIndicatorsAsCode = 0x0002,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ Microsoft.CodeAnalysis.Testing.MarkupMode.IgnoreFixable = 2 -> Microsoft.CodeAna
|
|||
Microsoft.CodeAnalysis.Testing.MarkupMode.None = 0 -> Microsoft.CodeAnalysis.Testing.MarkupMode
|
||||
Microsoft.CodeAnalysis.Testing.MarkupOptions
|
||||
Microsoft.CodeAnalysis.Testing.MarkupOptions.None = 0 -> Microsoft.CodeAnalysis.Testing.MarkupOptions
|
||||
Microsoft.CodeAnalysis.Testing.MarkupOptions.TreatPositionIndicatorsAsCode = 2 -> Microsoft.CodeAnalysis.Testing.MarkupOptions
|
||||
Microsoft.CodeAnalysis.Testing.MarkupOptions.UseFirstDescriptor = 1 -> Microsoft.CodeAnalysis.Testing.MarkupOptions
|
||||
Microsoft.CodeAnalysis.Testing.MetadataReferenceCollection
|
||||
Microsoft.CodeAnalysis.Testing.MetadataReferenceCollection.Add(System.Reflection.Assembly assembly) -> void
|
||||
|
@ -337,6 +338,7 @@ static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetPositionAndSpans(s
|
|||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetPositionAndSpans(string input, out string output, out int? cursorPosition, out System.Collections.Immutable.ImmutableDictionary<string, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextSpan>> spans) -> void
|
||||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetPositionsAndSpans(string input, out string output, out System.Collections.Immutable.ImmutableArray<int> positions, out System.Collections.Immutable.ImmutableDictionary<string, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextSpan>> spans) -> void
|
||||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetSpan(string input, out string output, out Microsoft.CodeAnalysis.Text.TextSpan span) -> void
|
||||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetSpans(string input, bool treatPositionIndicatorsAsCode, out string output, out System.Collections.Immutable.ImmutableDictionary<string, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextSpan>> spans) -> void
|
||||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetSpans(string input, out string output, out System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextSpan> spans) -> void
|
||||
static Microsoft.CodeAnalysis.Testing.TestFileMarkupParser.GetSpans(string input, out string output, out System.Collections.Immutable.ImmutableDictionary<string, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextSpan>> spans) -> void
|
||||
static readonly Microsoft.CodeAnalysis.Testing.DiagnosticResult.EmptyDiagnosticResults -> Microsoft.CodeAnalysis.Testing.DiagnosticResult[]
|
||||
|
|
|
@ -360,7 +360,19 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
var diagnostics = new List<DiagnosticResult>(explicitDiagnostics.Select(diagnostic => diagnostic.WithDefaultPath(defaultPath)));
|
||||
foreach ((var filename, var content) in sources)
|
||||
{
|
||||
TestFileMarkupParser.GetPositionsAndSpans(content.ToString(), out var output, out var positions, out var namedSpans);
|
||||
string output;
|
||||
ImmutableArray<int> positions;
|
||||
ImmutableDictionary<string, ImmutableArray<TextSpan>> namedSpans;
|
||||
if (markupOptions.HasFlag(MarkupOptions.TreatPositionIndicatorsAsCode))
|
||||
{
|
||||
positions = ImmutableArray<int>.Empty;
|
||||
TestFileMarkupParser.GetSpans(content.ToString(), treatPositionIndicatorsAsCode: true, out output, out namedSpans);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestFileMarkupParser.GetPositionsAndSpans(content.ToString(), out output, out positions, out namedSpans);
|
||||
}
|
||||
|
||||
sourceFiles.Add((filename, content.Replace(new TextSpan(0, content.Length), output)));
|
||||
if (positions.IsEmpty && namedSpans.IsEmpty)
|
||||
{
|
||||
|
|
|
@ -61,9 +61,9 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
@"\| (\#\d+) \}",
|
||||
RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
private static void Parse(string input, out string output, out ImmutableArray<int> positions, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
private static void Parse(string input, bool treatPositionIndicatorsAsCode, out string output, out ImmutableArray<int> positions, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
{
|
||||
Parse(input, out output, out positions, out var startPositions, out var endPositions);
|
||||
Parse(input, treatPositionIndicatorsAsCode, out output, out positions, out var startPositions, out var endPositions);
|
||||
if (startPositions.Length != endPositions.Length)
|
||||
{
|
||||
throw new ArgumentException($"The input contained '{startPositions.Length}' starting spans and '{endPositions.Length}' ending spans.");
|
||||
|
@ -162,6 +162,8 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
/// Parses the input markup to find standalone positions and the start and end positions of text spans.
|
||||
/// </summary>
|
||||
/// <param name="input">The input markup.</param>
|
||||
/// <param name="treatPositionIndicatorsAsCode"><see langword="true"/> to treat <c>$$</c> as literal code;
|
||||
/// otherwise, <see langword="false"/> to treat <c>$$</c> as a position in markup.</param>
|
||||
/// <param name="output">The output content with markup syntax removed from <paramref name="input"/>.</param>
|
||||
/// <param name="positions">A list of positions defined in markup (<c>$$</c>).</param>
|
||||
/// <param name="startPositions">A list of starting positions of spans in markup. The key of the element is a
|
||||
|
@ -172,7 +174,7 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
/// position (the location of the <c>|]</c> or <c>|}</c>). The value of the element is the <c>#id</c> content of
|
||||
/// a <c>|#id}</c> ending syntax, or <see langword="null"/> if the <c>|]</c> or <c>|}</c> syntax was used. This
|
||||
/// list preserves the original order of the ending markup tags in the input.</param>
|
||||
private static void Parse(string input, out string output, out ImmutableArray<int> positions, out ImmutableArray<(int inputPosition, int outputPosition, string key)> startPositions, out ImmutableArray<(int inputPosition, int outputPosition, string key)> endPositions)
|
||||
private static void Parse(string input, bool treatPositionIndicatorsAsCode, out string output, out ImmutableArray<int> positions, out ImmutableArray<(int inputPosition, int outputPosition, string key)> startPositions, out ImmutableArray<(int inputPosition, int outputPosition, string key)> endPositions)
|
||||
{
|
||||
var positionsBuilder = ImmutableArray.CreateBuilder<int>();
|
||||
var startPositionsBuilder = ImmutableArray.CreateBuilder<(int inputPosition, int outputPosition, string key)>();
|
||||
|
@ -188,7 +190,11 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
{
|
||||
matches.Clear();
|
||||
|
||||
AddMatch(input, PositionString, currentIndexInInput, matches);
|
||||
if (!treatPositionIndicatorsAsCode)
|
||||
{
|
||||
AddMatch(input, PositionString, currentIndexInInput, matches);
|
||||
}
|
||||
|
||||
AddMatch(input, SpanStartString, currentIndexInInput, matches);
|
||||
AddMatch(input, SpanEndString, currentIndexInInput, matches);
|
||||
AddMatch(input, NamedSpanEndString, currentIndexInInput, matches);
|
||||
|
@ -245,7 +251,7 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
|
||||
switch (matchString.Substring(0, 2))
|
||||
{
|
||||
case PositionString:
|
||||
case PositionString when !treatPositionIndicatorsAsCode:
|
||||
positionsBuilder.Add(matchIndexInOutput);
|
||||
break;
|
||||
|
||||
|
@ -335,12 +341,12 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
|
||||
public static void GetPositionsAndSpans(string input, out string output, out ImmutableArray<int> positions, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
{
|
||||
Parse(input, out output, out positions, out spans);
|
||||
Parse(input, treatPositionIndicatorsAsCode: false, out output, out positions, out spans);
|
||||
}
|
||||
|
||||
public static void GetPositionAndSpans(string input, out string output, out int? cursorPosition, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
{
|
||||
Parse(input, out output, out var positions, out spans);
|
||||
Parse(input, treatPositionIndicatorsAsCode: false, out output, out var positions, out spans);
|
||||
cursorPosition = positions.SingleOrNull();
|
||||
}
|
||||
|
||||
|
@ -357,12 +363,17 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
|
||||
public static void GetSpans(string input, out string output, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
{
|
||||
GetPositionAndSpans(input, out output, out int? _, out spans);
|
||||
GetSpans(input, treatPositionIndicatorsAsCode: false, out output, out spans);
|
||||
}
|
||||
|
||||
public static void GetSpans(string input, bool treatPositionIndicatorsAsCode, out string output, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans)
|
||||
{
|
||||
Parse(input, treatPositionIndicatorsAsCode, out output, out _, out spans);
|
||||
}
|
||||
|
||||
public static void GetPositionAndSpans(string input, out string output, out int? cursorPosition, out ImmutableArray<TextSpan> spans)
|
||||
{
|
||||
Parse(input, out output, out var positions, out var dictionary);
|
||||
Parse(input, treatPositionIndicatorsAsCode: false, out output, out var positions, out var dictionary);
|
||||
cursorPosition = positions.SingleOrNull();
|
||||
|
||||
spans = dictionary.GetValueOrDefault(string.Empty, ImmutableArray<TextSpan>.Empty);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Xunit;
|
||||
|
@ -96,6 +95,45 @@ namespace Microsoft.CodeAnalysis.Testing
|
|||
Assert.Equal(markup, TestFileMarkupParser.CreateTestFile(output, cursorPosition, spans));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SinglePosition7()
|
||||
{
|
||||
var markup = "first$$second";
|
||||
var expected = "firstsecond";
|
||||
|
||||
TestFileMarkupParser.GetSpans(markup, out var output, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans);
|
||||
Assert.Equal(expected, output);
|
||||
|
||||
// Test round-trip
|
||||
Assert.Equal(expected, TestFileMarkupParser.CreateTestFile(output, ImmutableArray<int>.Empty, spans));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SinglePosition8()
|
||||
{
|
||||
var markup = "first$$second";
|
||||
var expected = "firstsecond";
|
||||
|
||||
TestFileMarkupParser.GetSpans(markup, treatPositionIndicatorsAsCode: false, out var output, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans);
|
||||
Assert.Equal(expected, output);
|
||||
|
||||
// Test round-trip
|
||||
Assert.Equal(expected, TestFileMarkupParser.CreateTestFile(output, ImmutableArray<int>.Empty, spans));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SinglePosition9()
|
||||
{
|
||||
var markup = "first$$second";
|
||||
var expected = "first$$second";
|
||||
|
||||
TestFileMarkupParser.GetSpans(markup, treatPositionIndicatorsAsCode: true, out var output, out ImmutableDictionary<string, ImmutableArray<TextSpan>> spans);
|
||||
Assert.Equal(expected, output);
|
||||
|
||||
// Test round-trip
|
||||
Assert.Equal(expected, TestFileMarkupParser.CreateTestFile(output, ImmutableArray<int>.Empty, spans));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MissingRequiredPosition1()
|
||||
{
|
||||
|
|
|
@ -43,6 +43,24 @@ class TestClass $${
|
|||
await new CSharpTest(nestedDiagnostics: false, hiddenDescriptors: false, reportAdditionalLocations: reportAdditionalLocations) { TestCode = testCode }.RunAsync();
|
||||
}
|
||||
|
||||
[Theory(Skip = "Raw strings are not supported for the version of Roslyn currently used in tests.")]
|
||||
[CombinatorialData]
|
||||
[WorkItem(1067, "https://github.com/dotnet/roslyn-sdk/issues/1067")]
|
||||
public async Task TestCSharpMarkupBraceSpansWithRawInterpolatedString(bool reportAdditionalLocations)
|
||||
{
|
||||
var testCode = @"
|
||||
class TestClass [|{|]
|
||||
string value = $$"""""" [|{{|]0}} """""";
|
||||
}
|
||||
";
|
||||
|
||||
await new CSharpTest(nestedDiagnostics: false, hiddenDescriptors: false, reportAdditionalLocations: reportAdditionalLocations)
|
||||
{
|
||||
TestCode = testCode,
|
||||
MarkupOptions = MarkupOptions.TreatPositionIndicatorsAsCode,
|
||||
}.RunAsync();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[CombinatorialData]
|
||||
[WorkItem(181, "https://github.com/dotnet/roslyn-sdk/issues/181")]
|
||||
|
|
Загрузка…
Ссылка в новой задаче