@@ -105,34 +105,49 @@ public async Task LoadSolutionInWorkspace(SharpIdeSolutionModel solutionModel, S
105105
106106 Guard . Against . Null ( _workspace ) ;
107107
108+ await LoadSolutionCoreAsync ( _sharpIdeSolutionModel . FilePath , cancellationToken ) ;
109+
110+ timer . Stop ( ) ;
111+ _logger . LogInformation ( "RoslynAnalysis: Solution loaded in {ElapsedMilliseconds}ms" , timer . ElapsedMilliseconds ) ;
112+ }
113+
114+ private async Task LoadSolutionCoreAsync ( string solutionFilePath , CancellationToken cancellationToken )
115+ {
108116 using ( var ___ = SharpIdeOtel . Source . StartActivity ( "RestoreSolution" ) )
109117 {
110118 // MsBuildProjectLoader doesn't do a restore which is absolutely required for resolving PackageReferences, if they have changed. I am guessing it just reads from project.assets.json
111- await _buildService . MsBuildAsync ( _sharpIdeSolutionModel . FilePath , BuildType . Restore , BuildStartedFlags . UserFacing , cancellationToken ) ;
119+ // It is important to note that a Workspace has no concept of MSBuild, nuget packages etc. It is just told about project references and "metadata" references, which are dlls. This is what MSBuild does - it reads the csproj, and most importantly resolves nuget package references to dlls
120+ await _buildService . MsBuildAsync ( solutionFilePath , BuildType . Restore , BuildStartedFlags . UserFacing , cancellationToken ) ;
112121 }
122+
113123 using ( var ___ = SharpIdeOtel . Source . StartActivity ( "OpenSolution" ) )
114124 {
115125 //_msBuildProjectLoader!.LoadMetadataForReferencedProjects = true;
116- var ( solutionInfo , projectFileInfos ) = await _msBuildProjectLoader ! . LoadSolutionInfoAsync ( _sharpIdeSolutionModel . FilePath , cancellationToken : cancellationToken ) ;
126+
127+ // This call is the expensive part - MSBuild is slow. There doesn't seem to be any incrementalism for solutions.
128+ // The best we could do to speed it up is do .LoadProjectInfoAsync for the single project, and somehow munge that into the existing solution
129+ var ( solutionInfo , projectFileInfos ) = await _msBuildProjectLoader ! . LoadSolutionInfoAsync ( solutionFilePath , cancellationToken : cancellationToken ) ;
117130 _projectFileInfoMap = projectFileInfos ;
131+
118132 var analyzerReferencePaths = solutionInfo . Projects
119133 . SelectMany ( p => p . AnalyzerReferences . OfType < IsolatedAnalyzerFileReference > ( ) . Select ( a => a . FullPath ) )
120134 . OfType < string > ( )
121135 . Distinct ( )
122136 . ToImmutableArray ( ) ;
123-
124137 await _analyzerFileWatcher . StartWatchingFiles ( analyzerReferencePaths ) ;
125- _workspace . ClearSolution ( ) ;
126- var solution = _workspace . AddSolution ( solutionInfo ) ;
138+
139+ // There doesn't appear to be any noticeable difference between ClearSolution + AddSolution vs OnSolutionReloaded
140+ //_workspace.OnSolutionReloaded(newSolutionInfo);
141+ _workspace ! . ClearSolution ( ) ;
142+ _workspace . AddSolution ( solutionInfo ) ;
127143
128144 // If these aren't added, IDiagnosticAnalyzerService will not return compiler analyzer diagnostics
129145 // Note that we aren't currently using IDiagnosticAnalyzerService
130146 //var solutionAnalyzerReferences = CreateSolutionLevelAnalyzerReferencesForWorkspace(_workspace);
131147 //solution = solution.WithAnalyzerReferences(solutionAnalyzerReferences);
132148 //_workspace.SetCurrentSolution(solution);
133149 }
134- timer . Stop ( ) ;
135- _logger . LogInformation ( "RoslynAnalysis: Solution loaded in {ElapsedMilliseconds}ms" , timer . ElapsedMilliseconds ) ;
150+
136151 _solutionLoadedTcs . SetResult ( ) ;
137152 }
138153
@@ -199,24 +214,12 @@ public async Task ReloadSolution(CancellationToken cancellationToken = default)
199214 using var _ = SharpIdeOtel . Source . StartActivity ( $ "{ nameof ( RoslynAnalysis ) } .{ nameof ( ReloadSolution ) } ") ;
200215 _logger . LogInformation ( "RoslynAnalysis: Reloading solution" ) ;
201216 await _solutionLoadedTcs . Task ;
217+ _solutionLoadedTcs = new TaskCompletionSource ( ) ;
202218 Guard . Against . Null ( _workspace , nameof ( _workspace ) ) ;
203219 Guard . Against . Null ( _msBuildProjectLoader , nameof ( _msBuildProjectLoader ) ) ;
204220
205- // It is important to note that a Workspace has no concept of MSBuild, nuget packages etc. It is just told about project references and "metadata" references, which are dlls. This is the what MSBuild does - it reads the csproj, and most importantly resolves nuget package references to dlls
206- await _buildService . MsBuildAsync ( _sharpIdeSolutionModel ! . FilePath , BuildType . Restore , BuildStartedFlags . UserFacing , cancellationToken ) ;
207- var __ = SharpIdeOtel . Source . StartActivity ( $ "{ nameof ( RoslynAnalysis ) } .MSBuildProjectLoader.LoadSolutionInfoAsync") ;
208- // This call is the expensive part - MSBuild is slow. There doesn't seem to be any incrementalism for solutions.
209- // The best we could do to speed it up is do .LoadProjectInfoAsync for the single project, and somehow munge that into the existing solution
210- var ( newSolutionInfo , projectFileInfos ) = await _msBuildProjectLoader . LoadSolutionInfoAsync ( _sharpIdeSolutionModel ! . FilePath , cancellationToken : cancellationToken ) ;
211- _projectFileInfoMap = projectFileInfos ;
212- __ ? . Dispose ( ) ;
221+ await LoadSolutionCoreAsync ( _sharpIdeSolutionModel ! . FilePath , cancellationToken ) ;
213222
214- var ___ = SharpIdeOtel . Source . StartActivity ( $ "{ nameof ( RoslynAnalysis ) } .Workspace.OnSolutionReloaded") ;
215- // There doesn't appear to be any noticeable difference between ClearSolution + AddSolution vs OnSolutionReloaded
216- //_workspace.OnSolutionReloaded(newSolutionInfo);
217- _workspace . ClearSolution ( ) ;
218- _workspace . AddSolution ( newSolutionInfo ) ;
219- ___ ? . Dispose ( ) ;
220223 _logger . LogInformation ( "RoslynAnalysis: Solution reloaded" ) ;
221224 }
222225
0 commit comments