@@ -284,10 +284,10 @@ function resolve_analysis_request(server::Server, request::AnalysisRequest)
284284 @goto next_request
285285 end
286286
287- initial_analysis = request. prev_analysis_result === nothing
287+ prev_result = request. prev_analysis_result
288288 cancellable_token = request. cancellable_token
289289 if cancellable_token != = nothing
290- begin_full_analysis_progress (server, cancellable_token, request. entry, initial_analysis )
290+ begin_full_analysis_progress (server, cancellable_token, request. entry, prev_result === nothing )
291291 end
292292
293293 local failed:: Bool = false
@@ -303,6 +303,9 @@ function resolve_analysis_request(server::Server, request::AnalysisRequest)
303303 if cancellable_token != = nothing
304304 end_full_analysis_progress (server, cancellable_token)
305305 end
306+ if prev_result != = nothing
307+ cleanup_prev_methods (prev_result)
308+ end
306309 failed && @goto next_request
307310 end
308311 tm = round (time () - s, digits= 2 )
@@ -316,7 +319,7 @@ function resolve_analysis_request(server::Server, request::AnalysisRequest)
316319 # This ensures that clients using pull diagnostics (textDocument/diagnostic) will
317320 # re-request diagnostics now that module context is available, allowing
318321 # lowering/macro-expansion-error diagnostics to be properly reported.
319- if initial_analysis && supports (server, :workspace , :diagnostics , :refreshSupport )
322+ if prev_result === nothing && supports (server, :workspace , :diagnostics , :refreshSupport )
320323 request_diagnostic_refresh! (server)
321324 end
322325
@@ -368,6 +371,33 @@ function has_any_parse_errors(server::Server, request::AnalysisRequest)
368371 end
369372end
370373
374+ # Delete methods defined in previous analysis modules.
375+ # This doesn't free memory (Method objects remain in Core.methodtable), but removes them
376+ # from reflection APIs like `methods()`, preventing stale methods from appearing in
377+ # signature help or completions.
378+ function cleanup_prev_methods (prev_result:: AnalysisResult )
379+ prev_modules = IdSet {Module} ()
380+ for analyzed_file_info in values (prev_result. analyzed_file_infos)
381+ for module_range_info in analyzed_file_info. module_range_infos
382+ push! (prev_modules, last (module_range_info))
383+ end
384+ end
385+ methods_to_delete = Method[]
386+ Base. visit (Core. methodtable) do m:: Method
387+ if parentmodule (m) in prev_modules
388+ push! (methods_to_delete, m)
389+ end
390+ end
391+ for m in methods_to_delete
392+ try
393+ Base. delete_method (m)
394+ catch e
395+ JETLS_DEV_MODE && @warn " Failed to delete method $m "
396+ JETLS_DEV_MODE && Base. showerror (stderr , e, catch_backtrace ())
397+ end
398+ end
399+ end
400+
371401function update_analysis_cache! (manager:: AnalysisManager , analysis_result:: AnalysisResult )
372402 analyzed_uris = analyzed_file_uris (analysis_result)
373403 store! (manager. cache) do cache
0 commit comments