|
' 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.
Imports System.Collections.Immutable
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.UnitTests
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.AdditionalFiles
Public Class AdditionalFileDiagnosticsTests
Inherits AbstractCrossLanguageUserDiagnosticTest
Private Shared ReadOnly s_compositionWithMockDiagnosticUpdateSourceRegistrationService As TestComposition = EditorTestCompositions.EditorFeatures
Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace, language As String) As (DiagnosticAnalyzer, CodeFixProvider)
Return (New AdditionalFileAnalyzer(), New AdditionalFileFixer())
End Function
<WpfFact>
Public Async Function TestAdditionalFiles() As Task
Dim input =
<Workspace>
<Project Language='C#' AssemblyName='CSharpAssembly1' CommonReferences='true'>
<Document FilePath="Test1.cs">
using System.Runtime.Serialization;
public class Cl$$ass1 : ISerializable
{
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
}
</Document>
</Project>
</Workspace>
Using workspace = EditorTestWorkspace.Create(input, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService)
Dim project = workspace.Projects.First()
Dim newSln = workspace.CurrentSolution.AddAdditionalDocument(DocumentId.CreateNewId(project.Id), "App.Config", SourceText.From("false"))
workspace.TryApplyChanges(newSln)
Dim diagnosticAndFix = Await GetDiagnosticAndFixAsync(workspace)
Dim codeAction = diagnosticAndFix.Item2.Fixes.First().Action
Dim operations = codeAction.GetOperationsAsync(CancellationToken.None).Result
Dim edit = operations.OfType(Of ApplyChangesOperation)().First()
Dim oldSolution = workspace.CurrentSolution
Dim updatedSolution = edit.ChangedSolution
Dim updatedDocument = SolutionUtilities.GetSingleChangedAdditionalDocument(oldSolution, updatedSolution)
Dim actual = updatedDocument.GetTextAsync().Result.ToString().Trim()
Assert.Equal("true", actual)
End Using
End Function
End Class
Public Class AdditionalFileAnalyzer
Inherits DiagnosticAnalyzer
Public Shared Rule As New DiagnosticDescriptor("OA1001", "Options test", "Serialization support has not been requested", "Test", DiagnosticSeverity.Error, True)
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
Get
Return ImmutableArray.Create(Rule)
End Get
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterSymbolAction(AddressOf AnalyzeSymbol, SymbolKind.NamedType)
End Sub
Private Shared Function IsSerializationAllowed(options As AnalyzerOptions) As Boolean
Dim serializationAllowed = False
For Each item In options.AdditionalFiles
If item.Path.EndsWith("app.config", StringComparison.OrdinalIgnoreCase) Then
Dim text = item.GetText()
Boolean.TryParse(text.Lines(0).ToString(), serializationAllowed)
End If
Next
Return serializationAllowed
End Function
Public Shared Sub AnalyzeSymbol(context As SymbolAnalysisContext)
Dim namedType = DirectCast(context.Symbol, INamedTypeSymbol)
If namedType.AllInterfaces.Contains(context.Compilation.GetTypeByMetadataName("System.Runtime.Serialization.ISerializable")) Then
If Not IsSerializationAllowed(context.Options) Then
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Symbol.Locations.First()))
End If
End If
End Sub
End Class
Public Class AdditionalFileFixer
Inherits CodeFixProvider
Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String)
Get
Return ImmutableArray.Create(AdditionalFileAnalyzer.Rule.Id)
End Get
End Property
Public NotOverridable Overrides Async Function RegisterCodeFixesAsync(context As CodeFixContext) As Task
Dim project = context.Document.Project
Dim appConfigDoc = project.AdditionalDocuments.Where(Function(d) d.Name.EndsWith("app.config", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault()
If appConfigDoc IsNot Nothing Then
Dim text = Await appConfigDoc.GetTextAsync().ConfigureAwait(False)
Dim newText = "true"
Dim newSln = appConfigDoc.Project.Solution.WithAdditionalDocumentText(appConfigDoc.Id, SourceText.From("true", text.Encoding))
#Disable Warning RS0005
context.RegisterCodeFix(CodeAction.Create("Request serialization permission", Function(ct) Task.FromResult(newSln)), context.Diagnostics)
#Enable Warning RS0005
End If
End Function
End Class
End Namespace
|