@@ -197,43 +197,73 @@ private void AnalyzeDocument(AnalysisModuleKey key, PythonAnalyzerEntry entry, I
197197 _analysisCompleteEvent . Reset ( ) ;
198198 _log ? . Log ( TraceEventType . Verbose , $ "Analysis of { entry . Module . Name } ({ entry . Module . ModuleType } ) queued") ;
199199
200- var snapshot = _dependencyResolver . NotifyChanges ( key , entry , dependencies ) ;
201-
200+ var graphVersion = _dependencyResolver . ChangeValue ( key , entry , dependencies ) ;
201+
202202 lock ( _syncObj ) {
203- if ( _version > snapshot . Version ) {
203+ if ( _version > graphVersion ) {
204204 return ;
205205 }
206206
207- _version = snapshot . Version ;
207+ _version = graphVersion ;
208+ _currentSession ? . Cancel ( ) ;
208209 }
209210
210- if ( snapshot . MissingKeys . Count > 0 ) {
211- LoadMissingDocuments ( entry . Module . Interpreter , snapshot . MissingKeys ) ;
212- }
211+ UpdateDependentEntriesDepth ( entry , dependencies , graphVersion ) ;
213212
214- if ( TryCreateSession ( snapshot , entry , cancellationToken , out var session ) ) {
213+ if ( TryCreateSession ( graphVersion , entry , cancellationToken , out var session ) ) {
215214 session . Start ( true ) ;
216215 }
217216 }
218217
219- private bool TryCreateSession ( DependencyGraphSnapshot < AnalysisModuleKey , PythonAnalyzerEntry > snapshot , PythonAnalyzerEntry entry , CancellationToken cancellationToken , out PythonAnalyzerSession session ) {
218+ private void UpdateDependentEntriesDepth ( PythonAnalyzerEntry entry , ImmutableArray < AnalysisModuleKey > dependentKeys , int graphVersion ) {
219+ if ( dependentKeys . Count == 0 ) {
220+ return ;
221+ }
222+
223+ var dependentEntries = new List < PythonAnalyzerEntry > ( ) ;
224+ lock ( _syncObj ) {
225+ if ( _version > graphVersion ) {
226+ return ;
227+ }
228+
229+ foreach ( var key in dependentKeys ) {
230+ if ( _analysisEntries . TryGetValue ( key , out var value ) ) {
231+ dependentEntries . Add ( value ) ;
232+ }
233+ }
234+ }
235+
236+ if ( dependentEntries . Count == 0 ) {
237+ return ;
238+ }
239+
240+ var depth = entry . Depth ;
241+ foreach ( var dependentEntry in dependentEntries ) {
242+ dependentEntry . SetDepth ( graphVersion , depth ) ;
243+ }
244+ }
245+
246+ private bool TryCreateSession ( int graphVersion , PythonAnalyzerEntry entry , CancellationToken cancellationToken , out PythonAnalyzerSession session ) {
220247 var analyzeUserModuleOutOfOrder = false ;
221248 lock ( _syncObj ) {
222249 if ( _currentSession != null ) {
223- if ( _currentSession . Version > snapshot . Version || _nextSession != null && _nextSession . Version > snapshot . Version ) {
250+ if ( _currentSession . Version > graphVersion || _nextSession != null && _nextSession . Version > graphVersion ) {
224251 session = null ;
225252 return false ;
226253 }
227254
228255 analyzeUserModuleOutOfOrder = ! _currentSession . IsCompleted && entry . IsUserModule && _currentSession . AffectedEntriesCount >= _maxTaskRunning ;
229- if ( _version > snapshot . Version && analyzeUserModuleOutOfOrder ) {
256+ if ( _version > graphVersion && analyzeUserModuleOutOfOrder ) {
230257 session = CreateSession ( null , entry , cancellationToken ) ;
231258 return true ;
232259 }
233260 }
234261 }
235262
236- if ( ! _dependencyResolver . TryCreateWalker ( snapshot . Version , out var walker ) ) {
263+ var snapshot = _dependencyResolver . CurrentGraphSnapshot ;
264+ LoadMissingDocuments ( entry . Module . Interpreter , snapshot . MissingKeys ) ;
265+
266+ if ( ! _dependencyResolver . TryCreateWalker ( snapshot , out var walker ) ) {
237267 session = null ;
238268 return false ;
239269 }
@@ -254,7 +284,6 @@ private bool TryCreateSession(DependencyGraphSnapshot<AnalysisModuleKey, PythonA
254284 return true ;
255285 }
256286
257- _currentSession . Cancel ( ) ;
258287 _nextSession = session = CreateSession ( walker , analyzeUserModuleOutOfOrder ? entry : null , cancellationToken ) ;
259288 return analyzeUserModuleOutOfOrder ;
260289 }
@@ -278,9 +307,37 @@ private PythonAnalyzerSession CreateSession(IDependencyChainWalker<AnalysisModul
278307 => new PythonAnalyzerSession ( _services , _progress , _analysisCompleteEvent , _startNextSession , _disposeToken . CancellationToken , cancellationToken , walker , _version , entry ) ;
279308
280309 private void LoadMissingDocuments ( IPythonInterpreter interpreter , ImmutableArray < AnalysisModuleKey > missingKeys ) {
281- foreach ( var ( moduleName , _, isTypeshed ) in missingKeys ) {
310+ if ( missingKeys . Count == 0 ) {
311+ return ;
312+ }
313+
314+ var foundKeys = ImmutableArray < AnalysisModuleKey > . Empty ;
315+ foreach ( var missingKey in missingKeys ) {
316+ lock ( _syncObj ) {
317+ if ( _analysisEntries . TryGetValue ( missingKey , out _ ) ) {
318+ continue ;
319+ }
320+ }
321+
322+ var ( moduleName , _, isTypeshed ) = missingKey ;
282323 var moduleResolution = isTypeshed ? interpreter . TypeshedResolution : interpreter . ModuleResolution ;
283- moduleResolution . GetOrLoadModule ( moduleName ) ;
324+ var module = moduleResolution . GetOrLoadModule ( moduleName ) ;
325+ if ( module != null && module . ModuleType != ModuleType . Unresolved ) {
326+ foundKeys = foundKeys . Add ( missingKey ) ;
327+ }
328+ }
329+
330+ if ( foundKeys . Count > 0 ) {
331+ foreach ( var foundKey in foundKeys ) {
332+ PythonAnalyzerEntry entry ;
333+ lock ( _syncObj ) {
334+ if ( ! _analysisEntries . TryGetValue ( foundKey , out entry ) ) {
335+ continue ;
336+ }
337+ }
338+
339+ _dependencyResolver . TryAddValue ( foundKey , entry , ImmutableArray < AnalysisModuleKey > . Empty ) ;
340+ }
284341 }
285342 }
286343 }
0 commit comments