|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeCleanup;
using Microsoft.CodeAnalysis.CodeCleanup.Providers;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.CodeCleanup
{
[UseExportProvider]
[Trait(Traits.Feature, Traits.Features.FixIncorrectTokens)]
public class FixIncorrectTokensTests
{
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithMatchingIf()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
endif|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
End If
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithMatchingIf_Directive()
{
var code = @"[|
#If c = 0 Then
#Endif|]";
var expected = @"
#If c = 0 Then
#End If";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithoutMatchingIf()
{
var code = @"
Module Program
Sub Main(args As String())
[|EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
End If
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithoutMatchingIf_Directive()
{
var code = @"[|
Class X
End Class
#Endif|]";
var expected = @"
Class X
End Class
#End If";
await VerifyAsync(code, expected);
}
[Fact(Skip = "889521")]
[WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_SameLineAsIf()
{
var code = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then [|EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
End If
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_SameLineAsIf_Invalid()
{
var code = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing [|EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing EndIf
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_SameLineAsIf_Directive()
{
var code = @"[|
#If c = 0 Then #Endif|]";
var expected = @"
#If c = 0 Then #Endif";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingTrivia()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
' Dummy Endif
EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
' Dummy Endif
End If
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingTrivia_Directive()
{
var code = @"[|
#If c = 0 Then
'#Endif
#Endif
|]";
var expected = @"
#If c = 0 Then
'#Endif
#End If
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_InvocationExpressionArgument()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
InvocationExpression EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
InvocationExpression EndIf
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_InvalidDirectiveCases()
{
var code = @"[|
' BadDirective cases
#If c = 0 Then
#InvocationExpression #Endif
#If c = 0 Then
InvocationExpression# #Endif
#If c = 0 Then
InvocationExpression #Endif
' Missing EndIfDirective cases
#If c = 0 Then
#InvocationExpression
#Endif
#If c = 0 Then
InvocationExpression#
#Endif
#If c = 0 Then
InvocationExpression
#Endif
|]";
var expected = @"
' BadDirective cases
#If c = 0 Then
#InvocationExpression #Endif
#If c = 0 Then
InvocationExpression# #Endif
#If c = 0 Then
InvocationExpression #Endif
' Missing EndIfDirective cases
#If c = 0 Then
#InvocationExpression
#End If
#If c = 0 Then
InvocationExpression#
#End If
#If c = 0 Then
InvocationExpression
#End If
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithTrailingTrivia()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
EndIf ' Dummy EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
End If ' Dummy EndIf
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithTrailingTrivia_Directive()
{
var code = @"[|
#If c = 0 Then
#Endif '#Endif
|]";
var expected = @"
#If c = 0 Then
#End If '#Endif
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithIdentifierTokenTrailingTrivia()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
EndIf IdentifierToken|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
End If IdentifierToken
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_InvalidDirectiveCases_02()
{
var code = @"[|
' BadDirective cases
#If c = 0 Then
#Endif #IdentifierToken
#If c = 0 Then
#Endif IdentifierToken#
#If c = 0 Then
#Endif IdentifierToken
' Missing EndIfDirective cases
#If c = 0 Then
#Endif
#IdentifierToken
#If c = 0 Then
#Endif
IdentifierToken#
#If c = 0 Then
#Endif
IdentifierToken
|]";
var expected = @"
' BadDirective cases
#If c = 0 Then
#End If #IdentifierToken
#If c = 0 Then
#End If IdentifierToken#
#If c = 0 Then
#End If IdentifierToken
' Missing EndIfDirective cases
#If c = 0 Then
#End If
#IdentifierToken
#If c = 0 Then
#End If
IdentifierToken#
#If c = 0 Then
#End If
IdentifierToken
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingAndTrailingTrivia()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
' Dummy EndIf
EndIf
' Dummy EndIf|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
' Dummy EndIf
End If
' Dummy EndIf
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingAndTrailingTrivia_Directive()
{
var code = @"[|
#If c = 0 Then
'#Endif
#Endif '#Endif
|]";
var expected = @"
#If c = 0 Then
'#Endif
#End If '#Endif
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingAndTrailingInvocationExpressions()
{
var code = @"
Module Program
Sub Main(args As String())
[|If args IsNot Nothing Then
System.Console.WriteLine(args)
IdentifierToken
EndIf
IdentifierToken|]
End Sub
End Module";
var expected = @"
Module Program
Sub Main(args As String())
If args IsNot Nothing Then
System.Console.WriteLine(args)
IdentifierToken
End If
IdentifierToken
End Sub
End Module";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(17313, "DevDiv_Projects/Roslyn")]
public async Task FixEndIfKeyword_WithLeadingAndTrailingInvocationExpressions_Directive()
{
var code = @"[|
' BadDirective cases
#If c = 0 Then
#InvalidTrivia #Endif #InvalidTrivia
#If c = 0 Then
InvalidTrivia #Endif InvalidTrivia
#If c = 0 Then
InvalidTrivia# #Endif InvalidTrivia#
' Missing EndIfDirective cases
#If c = 0 Then
#InvalidTrivia
#Endif #InvalidTrivia
#If c = 0 Then
InvalidTrivia
#Endif InvalidTrivia
#If c = 0 Then
InvalidTrivia#
#Endif InvalidTrivia#
|]";
var expected = @"
' BadDirective cases
#If c = 0 Then
#InvalidTrivia #Endif #InvalidTrivia
#If c = 0 Then
InvalidTrivia #Endif InvalidTrivia
#If c = 0 Then
InvalidTrivia# #Endif InvalidTrivia#
' Missing EndIfDirective cases
#If c = 0 Then
#InvalidTrivia
#End If #InvalidTrivia
#If c = 0 Then
InvalidTrivia
#End If InvalidTrivia
#If c = 0 Then
InvalidTrivia#
#End If InvalidTrivia#
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(5722, "DevDiv_Projects/Roslyn")]
public async Task FixPrimitiveTypeKeywords_ValidCases()
{
var code = @"[|
Imports SystemAlias = System
Imports SystemInt16Alias = System.Short
Imports SystemUInt16Alias = System.ushort
Imports SystemInt32Alias = System.INTEGER
Imports SystemUInt32Alias = System.UInteger
Imports SystemInt64Alias = System.Long
Imports SystemUInt64Alias = System.uLong
Imports SystemDateTimeAlias = System.Date
Module Program
Sub Main(args As String())
Dim a1 As System.Short = 0
Dim b1 As SystemAlias.SHORT = a1
Dim c1 As SystemInt16Alias = b1
Dim a2 As System.UShort = 0
Dim b2 As SystemAlias.USHORT = a2
Dim c2 As SystemUInt16Alias = b2
Dim a3 As System.Integer = 0
Dim b3 As SystemAlias.INTEGER = a3
Dim c3 As SystemInt32Alias = b3
Dim a4 As System.UInteger = 0
Dim b4 As SystemAlias.UINTEGER = a4
Dim c4 As SystemUInt32Alias = b4
Dim a5 As System.Long = 0
Dim b5 As SystemAlias.LONG = a5
Dim c5 As SystemInt64Alias = b5
Dim a6 As System.ULong = 0
Dim b6 As SystemAlias.ULONG = 0
Dim c6 As SystemUInt64Alias = 0
Dim a7 As System.Date = Nothing
Dim b7 As SystemAlias.DATE = Nothing
Dim c7 As SystemDateTimeAlias = Nothing
End Sub
End Module
|]";
var expected = @"
Imports SystemAlias = System
Imports SystemInt16Alias = System.Int16
Imports SystemUInt16Alias = System.UInt16
Imports SystemInt32Alias = System.Int32
Imports SystemUInt32Alias = System.UInt32
Imports SystemInt64Alias = System.Int64
Imports SystemUInt64Alias = System.UInt64
Imports SystemDateTimeAlias = System.DateTime
Module Program
Sub Main(args As String())
Dim a1 As System.Int16 = 0
Dim b1 As SystemAlias.Int16 = a1
Dim c1 As SystemInt16Alias = b1
Dim a2 As System.UInt16 = 0
Dim b2 As SystemAlias.UInt16 = a2
Dim c2 As SystemUInt16Alias = b2
Dim a3 As System.Int32 = 0
Dim b3 As SystemAlias.Int32 = a3
Dim c3 As SystemInt32Alias = b3
Dim a4 As System.UInt32 = 0
Dim b4 As SystemAlias.UInt32 = a4
Dim c4 As SystemUInt32Alias = b4
Dim a5 As System.Int64 = 0
Dim b5 As SystemAlias.Int64 = a5
Dim c5 As SystemInt64Alias = b5
Dim a6 As System.UInt64 = 0
Dim b6 As SystemAlias.UInt64 = 0
Dim c6 As SystemUInt64Alias = 0
Dim a7 As System.DateTime = Nothing
Dim b7 As SystemAlias.DateTime = Nothing
Dim c7 As SystemDateTimeAlias = Nothing
End Sub
End Module
";
await VerifyAsync(code, expected);
}
[Fact, WorkItem(5722, "DevDiv_Projects/Roslyn")]
public async Task FixPrimitiveTypeKeywords_InvalidCases()
{
// With a user defined type named System
// No fixups as System binds to type not a namespace.
var code = @"
Imports SystemAlias = System
Imports SystemInt16Alias = System.Short
Imports SystemUInt16Alias = System.ushort
Imports SystemInt32Alias = System.INTEGER
Imports SystemUInt32Alias = System.UInteger
Imports SystemInt64Alias = System.Long
Imports SystemUInt64Alias = System.uLong
Imports SystemDateTimeAlias = System.Date
Class System
End Class
Module Program
Sub Main(args As String())
Dim a1 As System.Short = 0
Dim b1 As SystemAlias.SHORT = a1
Dim c1 As SystemInt16Alias = b1
Dim d1 As System.System.Short = 0
Dim e1 As Short = 0
Dim a2 As System.UShort = 0
Dim b2 As SystemAlias.USHORT = a2
Dim c2 As SystemUInt16Alias = b2
Dim d2 As System.System.UShort = 0
Dim e2 As UShort = 0
Dim a3 As System.Integer = 0
Dim b3 As SystemAlias.INTEGER = a3
Dim c3 As SystemInt32Alias = b3
Dim d3 As System.System.Integer = 0
Dim e3 As Integer = 0
Dim a4 As System.UInteger = 0
Dim b4 As SystemAlias.UINTEGER = a4
Dim c4 As SystemUInt32Alias = b4
Dim d4 As System.System.UInteger = 0
Dim e4 As UInteger = 0
Dim a5 As System.Long = 0
Dim b5 As SystemAlias.LONG = a5
Dim c5 As SystemInt64Alias = b5
Dim d5 As System.System.Long = 0
Dim e5 As Long = 0
Dim a6 As System.ULong = 0
Dim b6 As SystemAlias.ULONG = 0
Dim c6 As SystemUInt64Alias = 0
Dim d6 As System.System.ULong = 0
Dim e6 As ULong = 0
Dim a7 As System.Date = Nothing
Dim b7 As SystemAlias.DATE = Nothing
Dim c7 As SystemDateTimeAlias = Nothing
Dim d7 As System.System.Date = 0
Dim e7 As Date = 0
End Sub
End Module
";
await VerifyAsync(@"[|" + code + @"|]", expectedResult: code);
// No Fixes in trivia
code = @"
Imports SystemAlias = System
'Imports SystemInt16Alias = System.Short
Module Program
Sub Main(args As String())
' Dim a1 As System.Short = 0
' Dim b1 As SystemAlias.SHORT = a1
End Sub
End Module
";
await VerifyAsync(@"[|" + code + @"|]", expectedResult: code);
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/606015")]
public async Task FixFullWidthSingleQuotes()
{
var code = @"[|
‘fullwidth 1
’fullwidth 2
‘‘fullwidth 3
’'fullwidth 4
'‘fullwidth 5
‘’fullwidth 6
‘’‘’fullwidth 7
'‘’‘’fullwidth 8|]";
var expected = @"
'fullwidth 1
'fullwidth 2
'‘fullwidth 3
''fullwidth 4
'‘fullwidth 5
'’fullwidth 6
'’‘’fullwidth 7
'‘’‘’fullwidth 8";
await VerifyAsync(code, expected);
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/707135")]
public async Task FixFullWidthSingleQuotes2()
{
var savedCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
try
{
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture("zh-CN");
var code = @"[|‘’fullwidth 1|]";
var expected = @"'’fullwidth 1";
await VerifyAsync(code, expected);
}
finally
{
System.Threading.Thread.CurrentThread.CurrentCulture = savedCulture;
}
}
private static string FixLineEndings(string text)
=> text.Replace("\r\n", "\n").Replace("\n", "\r\n");
private static async Task VerifyAsync(string codeWithMarker, string expectedResult)
{
codeWithMarker = FixLineEndings(codeWithMarker);
expectedResult = FixLineEndings(expectedResult);
MarkupTestFile.GetSpans(codeWithMarker, out var codeWithoutMarker, out var textSpans);
var document = CreateDocument(codeWithoutMarker, LanguageNames.VisualBasic);
var codeCleanups = CodeCleaner.GetDefaultProviders(document).WhereAsArray(p => p.Name is PredefinedCodeCleanupProviderNames.FixIncorrectTokens or PredefinedCodeCleanupProviderNames.Format);
var cleanDocument = await CodeCleaner.CleanupAsync(document, textSpans[0], await document.GetCodeCleanupOptionsAsync(CancellationToken.None), codeCleanups);
Assert.Equal(expectedResult, (await cleanDocument.GetSyntaxRootAsync()).ToFullString());
}
private static Document CreateDocument(string code, string language)
{
var solution = new AdhocWorkspace().CurrentSolution;
var projectId = ProjectId.CreateNewId();
var project = solution.AddProject(projectId, "Project", "Project.dll", language).GetProject(projectId);
return project.AddMetadataReference(NetFramework.mscorlib)
.AddDocument("Document", SourceText.From(code));
}
}
}
|