diff --git a/src/Compiler/Service/ItemKey.fs b/src/Compiler/Service/ItemKey.fs index 6f364e2cdd7..39a3b30e48e 100644 --- a/src/Compiler/Service/ItemKey.fs +++ b/src/Compiler/Service/ItemKey.fs @@ -306,6 +306,21 @@ and [] ItemKeyStoreBuilder() = | ParentNone -> writeChar '%' | Parent eref -> writeEntityRef eref + let writeValue (vref: ValRef) = + if vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then + writeString ItemKeyTags.itemProperty + writeString vref.PropertyName + + match vref.IsOverrideOrExplicitImpl, vref.MemberInfo with + | true, Some { ImplementedSlotSigs = slotSig :: _ } -> slotSig.DeclaringType |> writeType false + | _ -> + + match vref.TryDeclaringEntity with + | ParentRef.Parent parent -> writeEntityRef parent + | _ -> () + else + writeValRef vref + let writeActivePatternCase (apInfo: ActivePatternInfo) index = writeString ItemKeyTags.itemActivePattern @@ -327,16 +342,7 @@ and [] ItemKeyStoreBuilder() = let preCount = b.Count match item with - | Item.Value vref -> - if vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then - writeString ItemKeyTags.itemProperty - writeString vref.PropertyName - - match vref.TryDeclaringEntity with - | ParentRef.Parent parent -> writeEntityRef parent - | _ -> () - else - writeValRef vref + | Item.Value vref -> writeValue vref | Item.UnionCase (info, _) -> writeString ItemKeyTags.typeUnionCase @@ -408,7 +414,7 @@ and [] ItemKeyStoreBuilder() = | Item.CtorGroup (_, [ info ]) -> match info with | FSMeth (_, ty, vref, _) when vref.IsConstructor -> writeType true ty - | FSMeth (_, _, vref, _) -> writeValRef vref + | FSMeth (_, _, vref, _) -> writeValue vref | ILMeth (_, info, _) -> info.ILMethodRef.ArgTypes |> List.iter writeILType writeILType info.ILMethodRef.ReturnType diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs index 8a68ca6b773..5e70c226c31 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs @@ -476,4 +476,76 @@ match 2 with | Even -> () | Odd -> () "FileFirst.fs", 2, 39, 43 //"FileFirst.fsi", 4, 6, 10 <-- this should also be found ]) - } \ No newline at end of file + } + + +module Interfaces = + + [] + let ``We find all references to interface methods`` () = + + let source = """ +type IInterface1 = + abstract member Method1 : int + +type IInterface2 = + abstract member Method2 : int + +type internal SomeType() = + + interface IInterface1 with + member _.Method1 = + 42 + + interface IInterface2 with + member this.Method2 = + (this :> IInterface1).Method1 + """ + + SyntheticProject.Create( { sourceFile "Program" [] with Source = source } ).Workflow { + placeCursor "Program" "Method1" + findAllReferences (expectToFind [ + "FileProgram.fs", 4, 20, 27 + "FileProgram.fs", 12, 17, 24 + "FileProgram.fs", 17, 12, 41 // Not sure why we get the whole range here, but it seems to work fine. + ]) + } + + [] + let ``We find all references to interface methods starting from implementation`` () = + + let source1 = """ +type IInterface1 = + abstract member Method1 : int + +type IInterface2 = + abstract member Method2 : int + """ + + let source2 = """ +open ModuleFirst + +type internal SomeType() = + + interface IInterface1 with + member _.Method1 = + 42 + + interface IInterface2 with + member this.Method2 = + (this :> IInterface1).Method1 + """ + + SyntheticProject.Create( + { sourceFile "First" [] with Source = source1 }, + { sourceFile "Second" [] with Source = source2 } + ).Workflow { + placeCursor "Second" "Method1" + findAllReferences (expectToFind [ + "FileFirst.fs", 4, 20, 27 + "FileSecond.fs", 8, 17, 24 + "FileSecond.fs", 13, 12, 41 // Not sure why we get the whole range here, but it seems to work fine. + ]) + } + +