Skip to content

Commit f79b95d

Browse files
committed
Fix SourceLink go-to-definition failure on .NET 10
When FSharp.Core is built on Linux (as in .NET 10), the PDB contains Linux-style paths. FSAC's getFileName was calling Path.GetFileName on non-Windows, which stripped the directory portion, causing the PDB document lookup to fail. Fix: - getFileName: Keep full FCS path, just normalize backslashes - compareRepoPath: Use suffix matching to handle workspace prefixes
1 parent e65df5d commit f79b95d

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

src/FsAutoComplete.Core/ParseAndCheckResults.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ type ParseAndCheckResults
4343
let logger = LogProvider.getLoggerByName "ParseAndCheckResults"
4444

4545
let getFileName (loc: range) =
46-
if Ionide.ProjInfo.ProjectSystem.Environment.isWindows then
47-
UMX.tag<NormalizedRepoPathSegment> loc.FileName
48-
else
49-
UMX.tag<NormalizedRepoPathSegment> (Path.GetFileName loc.FileName)
46+
// Keep the full FCS path, just normalize backslashes to forward slashes.
47+
// FCS may prepend a workspace prefix if the PDB path isn't absolute on this platform.
48+
// The comparison in Sourcelink.compareRepoPath will handle the prefix via suffix matching.
49+
let normalized = loc.FileName.Replace('\\', '/')
50+
UMX.tag<NormalizedRepoPathSegment> normalized
5051

5152
member __.TryFindDeclaration (pos: Position) (lineStr: LineStr) =
5253
async {

src/FsAutoComplete.Core/Sourcelink.fs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,42 @@ type private Document =
4646
Language: System.Guid
4747
IsEmbedded: bool }
4848

49-
let private compareRepoPath (d: Document) targetFile =
50-
if Environment.isWindows then
51-
let s = UMX.untag d.Name
52-
let s' = normalizePath s |> UMX.untag
53-
let s' = UMX.tag<NormalizedRepoPathSegment> s'
54-
s' = targetFile
55-
else
56-
let t = UMX.untag targetFile |> UMX.tag<RepoPathSegment>
57-
let t' = normalizeRepoPath t
58-
normalizeRepoPath d.Name = t'
49+
let private compareRepoPath (d: Document) fcsPath =
50+
// The fcsPath is the full path from FCS (normalized, backslashes converted to forward slashes).
51+
// FCS may prepend a workspace prefix if the PDB path wasn't absolute on this platform.
52+
// The d.Name is a PDB document entry (the original path from when the DLL was compiled).
53+
//
54+
// The PDB document should be a SUFFIX of (or equal to) the FCS path:
55+
// - FCS path: /workspaces/project/D:/a/_work/1/s/src/FSharp.Core/list.fs
56+
// - PDB doc: D:/a/_work/1/s/src/FSharp.Core/list.fs
57+
// → fcsPath.EndsWith("/" + pdbDoc) = true
58+
//
59+
// - FCS path: /__w/1/s/src/fsharp/src/FSharp.Core/list.fs
60+
// - PDB doc: /__w/1/s/src/fsharp/src/FSharp.Core/list.fs
61+
// → fcsPath == pdbDoc = true
62+
63+
let docNormalized: string<NormalizedRepoPathSegment> =
64+
if Environment.isWindows then
65+
let s = UMX.untag d.Name
66+
let normalized = normalizePath s |> UMX.untag
67+
UMX.tag<NormalizedRepoPathSegment> normalized
68+
else
69+
normalizeRepoPath d.Name
70+
71+
let fcsNormalized: string<NormalizedRepoPathSegment> =
72+
if Environment.isWindows then
73+
fcsPath
74+
else
75+
let t: string = UMX.untag fcsPath
76+
let tagged: string<RepoPathSegment> = UMX.tag<RepoPathSegment> t
77+
normalizeRepoPath tagged
78+
79+
let docStr = UMX.untag docNormalized
80+
let fcsStr = UMX.untag fcsNormalized
81+
82+
// PDB doc should be suffix of (or equal to) FCS path
83+
fcsStr = docStr
84+
|| fcsStr.EndsWith("/" + docStr, System.StringComparison.Ordinal)
5985

6086
let private pdbForDll (dllPath: string<LocalPath>) =
6187
UMX.tag<LocalPath> (Path.ChangeExtension(UMX.untag dllPath, ".pdb"))

0 commit comments

Comments
 (0)