Skip to content

Commit 9df89d2

Browse files
authored
Fix finding references to interface methods (#15829)
1 parent 791bef9 commit 9df89d2

File tree

2 files changed

+90
-12
lines changed

2 files changed

+90
-12
lines changed

src/Compiler/Service/ItemKey.fs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,21 @@ and [<Sealed>] ItemKeyStoreBuilder() =
306306
| ParentNone -> writeChar '%'
307307
| Parent eref -> writeEntityRef eref
308308

309+
let writeValue (vref: ValRef) =
310+
if vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then
311+
writeString ItemKeyTags.itemProperty
312+
writeString vref.PropertyName
313+
314+
match vref.IsOverrideOrExplicitImpl, vref.MemberInfo with
315+
| true, Some { ImplementedSlotSigs = slotSig :: _ } -> slotSig.DeclaringType |> writeType false
316+
| _ ->
317+
318+
match vref.TryDeclaringEntity with
319+
| ParentRef.Parent parent -> writeEntityRef parent
320+
| _ -> ()
321+
else
322+
writeValRef vref
323+
309324
let writeActivePatternCase (apInfo: ActivePatternInfo) index =
310325
writeString ItemKeyTags.itemActivePattern
311326

@@ -327,16 +342,7 @@ and [<Sealed>] ItemKeyStoreBuilder() =
327342
let preCount = b.Count
328343

329344
match item with
330-
| Item.Value vref ->
331-
if vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then
332-
writeString ItemKeyTags.itemProperty
333-
writeString vref.PropertyName
334-
335-
match vref.TryDeclaringEntity with
336-
| ParentRef.Parent parent -> writeEntityRef parent
337-
| _ -> ()
338-
else
339-
writeValRef vref
345+
| Item.Value vref -> writeValue vref
340346

341347
| Item.UnionCase (info, _) ->
342348
writeString ItemKeyTags.typeUnionCase
@@ -408,7 +414,7 @@ and [<Sealed>] ItemKeyStoreBuilder() =
408414
| Item.CtorGroup (_, [ info ]) ->
409415
match info with
410416
| FSMeth (_, ty, vref, _) when vref.IsConstructor -> writeType true ty
411-
| FSMeth (_, _, vref, _) -> writeValRef vref
417+
| FSMeth (_, _, vref, _) -> writeValue vref
412418
| ILMeth (_, info, _) ->
413419
info.ILMethodRef.ArgTypes |> List.iter writeILType
414420
writeILType info.ILMethodRef.ReturnType

tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,4 +476,76 @@ match 2 with | Even -> () | Odd -> ()
476476
"FileFirst.fs", 2, 39, 43
477477
//"FileFirst.fsi", 4, 6, 10 <-- this should also be found
478478
])
479-
}
479+
}
480+
481+
482+
module Interfaces =
483+
484+
[<Fact>]
485+
let ``We find all references to interface methods`` () =
486+
487+
let source = """
488+
type IInterface1 =
489+
abstract member Method1 : int
490+
491+
type IInterface2 =
492+
abstract member Method2 : int
493+
494+
type internal SomeType() =
495+
496+
interface IInterface1 with
497+
member _.Method1 =
498+
42
499+
500+
interface IInterface2 with
501+
member this.Method2 =
502+
(this :> IInterface1).Method1
503+
"""
504+
505+
SyntheticProject.Create( { sourceFile "Program" [] with Source = source } ).Workflow {
506+
placeCursor "Program" "Method1"
507+
findAllReferences (expectToFind [
508+
"FileProgram.fs", 4, 20, 27
509+
"FileProgram.fs", 12, 17, 24
510+
"FileProgram.fs", 17, 12, 41 // Not sure why we get the whole range here, but it seems to work fine.
511+
])
512+
}
513+
514+
[<Fact>]
515+
let ``We find all references to interface methods starting from implementation`` () =
516+
517+
let source1 = """
518+
type IInterface1 =
519+
abstract member Method1 : int
520+
521+
type IInterface2 =
522+
abstract member Method2 : int
523+
"""
524+
525+
let source2 = """
526+
open ModuleFirst
527+
528+
type internal SomeType() =
529+
530+
interface IInterface1 with
531+
member _.Method1 =
532+
42
533+
534+
interface IInterface2 with
535+
member this.Method2 =
536+
(this :> IInterface1).Method1
537+
"""
538+
539+
SyntheticProject.Create(
540+
{ sourceFile "First" [] with Source = source1 },
541+
{ sourceFile "Second" [] with Source = source2 }
542+
).Workflow {
543+
placeCursor "Second" "Method1"
544+
findAllReferences (expectToFind [
545+
"FileFirst.fs", 4, 20, 27
546+
"FileSecond.fs", 8, 17, 24
547+
"FileSecond.fs", 13, 12, 41 // Not sure why we get the whole range here, but it seems to work fine.
548+
])
549+
}
550+
551+

0 commit comments

Comments
 (0)