dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.92k stars 4.01k forks source link

API: Analyzer redirecting #74989

Closed jjonescz closed 3 days ago

jjonescz commented 1 week ago

Background and Motivation

As part of https://github.com/dotnet/sdk/issues/42087 (see also https://github.com/dotnet/sdk/pull/42437 for design doc), we want to introduce a VSIX deployed as part of the dotnet/sdk repo which would be able to control how analyzers are loaded in Roslyn. Specifically, it should be able to redirect analyzers that would normally load from SDK to analyzers that will be deployed as part of Visual Studio install. The intention is to avoid compiler version mismatch (the analyzers from SDK can reference an incompatible version of Roslyn whereas the VS-inserted analyzers will match the Roslyn coming in the same VS).

Proposed API

/// <summary>
/// Any MEF component implementing this interface will be used to redirect analyzer assemblies.
/// </summary>
[Experimental(...)]
public interface IAnalyzerAssemblyRedirector
{
    /// <summary>
    /// Consulted whenever an <see cref="AnalyzerFileReference"/> is created to determine its full path.
    /// </summary>
    /// <param name="fullPath">
    /// Original full path of the analyzer assembly.
    /// </param>
    /// <returns>
    /// The redirected full path of the analyzer assembly
    /// or <see langword="null"/> if this instance cannot redirect the given assembly.
    /// </returns>
    /// <remarks>
    /// If two redirects return different paths for the same assembly, no redirection will be performed.
    /// </remarks>
    string? RedirectPath(string fullPath);
}

Usage Examples

[Export(typeof(IAnalyzerAssemblyRedirector))]
public sealed class SdkAnalyzerAssemblyRedirector : IAnalyzerAssemblyRedirector
{
    public string? RedirectPath(string fullPath)
    {
        if (AnalyzerMap.TryGetValue(fullPath, out string redirectedFullPath))
        {
            return redirectedFullPath;
        }

        return null;
    }
}

Alternative Designs

Risks

The API is marked Experimental, so we should be able to change/remove it at any point if we want.

333fred commented 1 week ago

API Review

Conclusion: Investigate making the API internal in the workspaces layer.