From 2a5ffb5e732bdd84e42109df0dab2efd94b840c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 15:32:33 +0000 Subject: [PATCH 1/3] Initial plan From b0c66f72bd83837542a8bd745ede35c7357aed25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 15:58:04 +0000 Subject: [PATCH 2/3] Fix thread safety issue: Replace Dictionary with ConcurrentDictionary in XmlDocumentation Provider Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- .../DocComments/XMLDocumentation.fs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs index 10db9697b56..95238bc523b 100644 --- a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs +++ b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs @@ -3,6 +3,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System +open System.Collections.Concurrent open System.Collections.Immutable open System.Runtime.CompilerServices open System.Text.RegularExpressions @@ -288,27 +289,28 @@ module internal XmlDocumentation = /// Provide Xml Documentation type Provider(xmlIndexService: IVsXMLMemberIndexService) = /// Index of assembly name to xml member index. - let cache = Dictionary() + let cache = ConcurrentDictionary() do Events.SolutionEvents.OnAfterCloseSolution.Add(fun _ -> cache.Clear()) /// Retrieve the preexisting xml index or None let GetMemberIndexOfAssembly (assemblyName) = - match cache.TryGetValue(assemblyName) with - | true, memberIndex -> Some(memberIndex) - | false, _ -> - let ok, memberIndex = xmlIndexService.CreateXMLMemberIndex(assemblyName) - - if Com.Succeeded(ok) then - let ok = memberIndex.BuildMemberIndex() - + let memberIndex = + cache.GetOrAdd(assemblyName, fun name -> + let ok, memberIndex = xmlIndexService.CreateXMLMemberIndex(name) if Com.Succeeded(ok) then - cache.Add(assemblyName, memberIndex) - Some(memberIndex) + let ok = memberIndex.BuildMemberIndex() + if Com.Succeeded(ok) then + memberIndex + else + null else - None - else - None + null) + + if memberIndex <> null then + Some(memberIndex) + else + None let AppendMemberData ( From 3d4a39e5daef126c0d1757a63f9eae35d304be28 Mon Sep 17 00:00:00 2001 From: GH Actions Date: Thu, 31 Jul 2025 08:35:01 +0000 Subject: [PATCH 3/3] Apply patch from /run fantomas --- .../DocComments/XMLDocumentation.fs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs index 95238bc523b..7c587b206c7 100644 --- a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs +++ b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs @@ -295,22 +295,20 @@ module internal XmlDocumentation = /// Retrieve the preexisting xml index or None let GetMemberIndexOfAssembly (assemblyName) = - let memberIndex = - cache.GetOrAdd(assemblyName, fun name -> - let ok, memberIndex = xmlIndexService.CreateXMLMemberIndex(name) - if Com.Succeeded(ok) then - let ok = memberIndex.BuildMemberIndex() + let memberIndex = + cache.GetOrAdd( + assemblyName, + fun name -> + let ok, memberIndex = xmlIndexService.CreateXMLMemberIndex(name) + if Com.Succeeded(ok) then - memberIndex + let ok = memberIndex.BuildMemberIndex() + if Com.Succeeded(ok) then memberIndex else null else null - else - null) - - if memberIndex <> null then - Some(memberIndex) - else - None + ) + + if memberIndex <> null then Some(memberIndex) else None let AppendMemberData (