diff --git a/src/Compiler/Service/ItemKey.fs b/src/Compiler/Service/ItemKey.fs index 9609ccf9c38..68977c68f1a 100644 --- a/src/Compiler/Service/ItemKey.fs +++ b/src/Compiler/Service/ItemKey.fs @@ -233,7 +233,10 @@ and [] ItemKeyStoreBuilder() = match stripTyparEqns ty with | TType_forall (_, ty) -> writeType false ty - | TType_app (tcref, _, _) -> writeEntityRef tcref + | TType_app (tcref, _, _) -> + match tcref.TypeAbbrev with + | Some ty -> writeType isStandalone ty + | None -> writeEntityRef tcref | TType_tuple (_, tinst) -> writeString ItemKeyTags.typeTuple diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs index 83131035443..41709e2fe74 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs @@ -195,4 +195,26 @@ let foo x = 5""" }) "FileSecond.fs", 8, 2, 4 "FileThird.fs", 8, 2, 13 ]) - } \ No newline at end of file + } + +[] +let ``We find a type that has been aliased`` () = + + let project = SyntheticProject.Create("TypeAliasTest", + { sourceFile "First" [] with + ExtraSource = "type MyInt = int32\n" + + "let myNum = 7" + SignatureFile = Custom ("module TypeAliasTest.ModuleFirst\n" + + "type MyInt = int32\n" + + "val myNum: MyInt") }, + { sourceFile "Second" [] with + ExtraSource = "let goo x = ModuleFirst.myNum + x"}) + + project.Workflow { + placeCursor "First" "myNum" + findAllReferences (expectToFind [ + "FileFirst.fs", 7, 4, 9 + "FileFirst.fsi", 3, 4, 9 + "FileSecond.fs", 6, 12, 29 + ]) + } diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs index a2abe1d67b1..c67a9e6c5b3 100644 --- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs +++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs @@ -596,6 +596,33 @@ type ProjectWorkflowBuilder return { ctx with Cursor = su } } + /// Find a symbol by finding the first occurrence of the symbol name in the file + [] + member this.PlaceCursor(workflow: Async, fileId, symbolName: string) = + async { + let! ctx = workflow + + let source = renderSourceFile ctx.Project (ctx.Project.Find fileId) + let index = source.IndexOf symbolName + let line = source |> Seq.take index |> Seq.where ((=) '\n') |> Seq.length + let fullLine = source.Split '\n' |> Array.item line + let colAtEndOfNames = fullLine.IndexOf symbolName + symbolName.Length + + let! results = checkFile fileId ctx.Project checker + let typeCheckResults = getTypeCheckResult results + + let su = + typeCheckResults.GetSymbolUseAtLocation(line + 1, colAtEndOfNames, fullLine, [symbolName]) + + if su.IsNone then + let file = ctx.Project.Find fileId + + failwith + $"No symbol found in {file.FileName} at {line}:{colAtEndOfNames}\nFile contents:\n\n{source}\n" + + return { ctx with Cursor = su } + } + /// Find all references within a single file, results are provided to the 'processResults' function [] member this.FindAllReferencesInFile(workflow: Async, fileId: string, processResults) = @@ -606,7 +633,7 @@ type ProjectWorkflowBuilder let symbolUse = ctx.Cursor |> Option.defaultWith (fun () -> - failwith $"Please place cursor at a valid location via {nameof this.PlaceCursor} first") + failwith $"Please place cursor at a valid location via placeCursor first") let file = ctx.Project.Find fileId let absFileName = ctx.Project.ProjectDir ++ file.FileName @@ -629,7 +656,7 @@ type ProjectWorkflowBuilder let symbolUse = ctx.Cursor |> Option.defaultWith (fun () -> - failwith $"Please place cursor at a valid location via {nameof this.PlaceCursor} first") + failwith $"Please place cursor at a valid location via placeCursor first") let! results = [ for f in options.SourceFiles do