Add solution analyzer references
This commit is contained in:
@@ -42,7 +42,7 @@ using DiagnosticSeverity = Microsoft.CodeAnalysis.DiagnosticSeverity;
|
|||||||
|
|
||||||
namespace SharpIDE.Application.Features.Analysis;
|
namespace SharpIDE.Application.Features.Analysis;
|
||||||
|
|
||||||
public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildService, AnalyzerFileWatcher analyzerFileWatcher)
|
public partial class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildService, AnalyzerFileWatcher analyzerFileWatcher)
|
||||||
{
|
{
|
||||||
private readonly ILogger<RoslynAnalysis> _logger = logger;
|
private readonly ILogger<RoslynAnalysis> _logger = logger;
|
||||||
private readonly BuildService _buildService = buildService;
|
private readonly BuildService _buildService = buildService;
|
||||||
@@ -136,6 +136,12 @@ public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildSe
|
|||||||
await _analyzerFileWatcher.StartWatchingFiles(analyzerReferencePaths);
|
await _analyzerFileWatcher.StartWatchingFiles(analyzerReferencePaths);
|
||||||
_workspace.ClearSolution();
|
_workspace.ClearSolution();
|
||||||
var solution = _workspace.AddSolution(solutionInfo);
|
var solution = _workspace.AddSolution(solutionInfo);
|
||||||
|
|
||||||
|
// If these aren't added, IDiagnosticAnalyzerService will not return compiler analyzer diagnostics
|
||||||
|
// Note that we aren't currently using IDiagnosticAnalyzerService
|
||||||
|
//var solutionAnalyzerReferences = CreateSolutionLevelAnalyzerReferencesForWorkspace(_workspace);
|
||||||
|
//solution = solution.WithAnalyzerReferences(solutionAnalyzerReferences);
|
||||||
|
//_workspace.SetCurrentSolution(solution);
|
||||||
}
|
}
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
_logger.LogInformation("RoslynAnalysis: Solution loaded in {ElapsedMilliseconds}ms", timer.ElapsedMilliseconds);
|
_logger.LogInformation("RoslynAnalysis: Solution loaded in {ElapsedMilliseconds}ms", timer.ElapsedMilliseconds);
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System.Collections.Immutable;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.Diagnostics;
|
||||||
|
using Microsoft.CodeAnalysis.Host;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Roslyn.Utilities;
|
||||||
|
|
||||||
|
namespace SharpIDE.Application.Features.Analysis;
|
||||||
|
|
||||||
|
public partial class RoslynAnalysis
|
||||||
|
{
|
||||||
|
// https://github.com/dotnet/roslyn/blob/a5ff3f7bcb8cb7116709009e7bbafc73ce2d4c79/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerWorkspaceFactory.cs#L81
|
||||||
|
public ImmutableArray<AnalyzerFileReference> CreateSolutionLevelAnalyzerReferencesForWorkspace(Workspace workspace)
|
||||||
|
{
|
||||||
|
var solutionLevelAnalyzerPaths = new DirectoryInfo(AppContext.BaseDirectory).GetFiles("*.dll")
|
||||||
|
.Where(f => f.Name.StartsWith("Microsoft.CodeAnalysis.", StringComparison.Ordinal) && !f.Name.Contains("LanguageServer", StringComparison.Ordinal))
|
||||||
|
.Select(f => f.FullName)
|
||||||
|
.ToImmutableArray();
|
||||||
|
|
||||||
|
var references = ImmutableArray.CreateBuilder<AnalyzerFileReference>();
|
||||||
|
var loaderProvider = workspace.Services.GetRequiredService<IAnalyzerAssemblyLoaderProvider>();
|
||||||
|
|
||||||
|
// Load all analyzers into a fresh shadow copied load context. In the future, if we want to support reloading
|
||||||
|
// of solution-level analyzer references, we should just need to listen for changes to those analyzer paths and
|
||||||
|
// then call back into this method to update the solution accordingly.
|
||||||
|
var analyzerLoader = loaderProvider.CreateNewShadowCopyLoader();
|
||||||
|
|
||||||
|
foreach (var analyzerPath in solutionLevelAnalyzerPaths)
|
||||||
|
{
|
||||||
|
if (File.Exists(analyzerPath))
|
||||||
|
{
|
||||||
|
references.Add(new AnalyzerFileReference(analyzerPath, analyzerLoader));
|
||||||
|
_logger.LogDebug($"Solution-level analyzer at {analyzerPath} added to workspace.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"Solution-level analyzer at {analyzerPath} could not be found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return references.ToImmutableAndClear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ public class RoslynAnalysisTests
|
|||||||
|
|
||||||
var roslynAnalysis = new RoslynAnalysis(logger, buildService, analyzerFileWatcher);
|
var roslynAnalysis = new RoslynAnalysis(logger, buildService, analyzerFileWatcher);
|
||||||
|
|
||||||
var solutionModel = await VsPersistenceMapper.GetSolutionModel(@"C:\Users\Matthew\Documents\Git\SharpIDE\SharpIDE.sln", TestContext.Current.CancellationToken);
|
var solutionModel = await VsPersistenceMapper.GetSolutionModel(@"C:\Users\Matthew\Documents\Git\SharpIDE\SharpIDE.slnx", TestContext.Current.CancellationToken);
|
||||||
var sharpIdeApplicationProject = solutionModel.AllProjects.Single(p => p.Name == "SharpIDE.Application");
|
var sharpIdeApplicationProject = solutionModel.AllProjects.Single(p => p.Name == "SharpIDE.Application");
|
||||||
|
|
||||||
var timer = Stopwatch.StartNew();
|
var timer = Stopwatch.StartNew();
|
||||||
|
|||||||
Reference in New Issue
Block a user